【问题标题】:IntegrityError at /users/signup NOT NULL constraint failed: users_user.username/users/signup NOT NULL 约束处​​的 IntegrityError 失败:users_user.username
【发布时间】:2021-06-06 11:37:54
【问题描述】:

我在做什么

我在 forms.py 中使用 ModelForm 并在 views.py 中使用 FormView 来制作注册表单。我让用户在登录时使用他们的电子邮件作为他们的用户名,以便他们在丢失时可以轻松设置新密码。

错误图片

它只是在我的控制台中抛出了IntegrityError

IntegrityError at / NOT NULL contraint failed

我试图解决的问题

  1. 我删除了所有的迁移文件和 db 文件,这样我的数据库中就不会有任何重复的用户。然后我创建了新的超级用户,然后创建了新用户。
  2. 我在Meta 类中删除了fields 中的email 字段,然后创建了电子邮件的清理方法(def clean_email(self):)。但是,此解决方案显然不起作用,因为它会删除我的注册表单中的电子邮件字段。

源代码

以下是我所有可能与该主题相关的源代码。

  1. 模板/用户/signup.html
{% block content %}
    <section id="signup">
        <form method="POST", action="{% url 'users:signup' %}">
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit">Signup</button>
        </form>
    </section>
{% endblock content %}
  1. users/forms.py
class SignupForm(forms.ModelForm):
    class Meta:
        model = models.User
        fields = ['first_name', 'last_name', 'email']

    password = forms.CharField(widget=forms.PasswordInput)
    confirm_password = forms.CharField(widget=forms.PasswordInput, label='Confirm Password')

    # Validating password 
    def clean_confirm_password(self):
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if password != confirm_password:
            raise forms.ValidationError('Password should be matched!')
        else: 
            return password 

    def save(self, *args, **kwargs):
        user = super().save(commit=False)
        username = self.cleaned_data.get('username')
        password = self.cleaned_data.get('password')
        user.username = username
        user.set_password = password 
        user.save()
  1. users/view.py
class SingupView(FormView):
    template_name = 'users/signup.html'
    form_class = forms.SignupForm
    success_url = reverse_lazy('common:home')

    def form_valid(self, form):
        form.save()
        email = form.cleaned_data.get('email')
        password = form.cleaned_data.get('password')
        user = authenticate(self.request, username=email, password=password)
        if user is not None:
            login(self.request, user)
        return super().form_valid(form) 

我的 github 仓库是https://github.com/donghhan/knowner-website.git

请帮帮我!

【问题讨论】:

    标签: python django django-views django-forms


    【解决方案1】:

    错误表明您没有将用户名添加为数据 在您的 SignupForm 中,您排除了该字段,因此出现错误

    1. 将其添加到表单中

      字段 = ['username','first_name', 'last_name', 'email']

    1. 修改用户模型,以不需要用户名的方式,你不能只传递电子邮件作为用户名,你需要改造模型,比如:

    从 AbstractBaseUser 继承并调整

    class NewUser(AbstractBaseUser, PermissionsMixin):
    
      email = models.EmailField(_('email address'), unique=True)
      #username = models.CharField(max_length=150, unique=True)
      first_name = models.CharField(max_length=150, blank=True)
      last_name = models.CharField(max_length=150, blank=True)
      start_date = models.DateTimeField(default=timezone.now)
      is_staff = models.BooleanField(default=False)
      is_active = models.BooleanField(default=True)
    
      objects = CustomManager()
    
      USERNAME_FIELD = 'email'
      REQUIRED_FIELDS = ['first_name','last_name'] # or as you decide
    
      def __str__(self):
          return self.email # or what you choose
    

    添加新用户模型的新管理器并进行一些验证

    class CustomManager(BaseUserManager):
    
    def create_superuser(self, email, username, first_name, password, **other_fields):
    
        other_fields.setdefault('is_staff', True)
        other_fields.setdefault('is_superuser', True)
        other_fields.setdefault('is_active', True)
    
        if other_fields.get('is_staff') is not True:
            raise ValueError(
                'Superuser must be assigned to is_staff=True.')
        if other_fields.get('is_superuser') is not True:
            raise ValueError(
                'Superuser must be assigned to is_superuser=True.')
    
        return self.create_user(email, username, first_name, password, **other_fields)
    
    def create_user(self, email, username, first_name, password, **other_fields):
    
        if not email:
            raise ValueError(_('You must provide an email address'))
    
        email = self.normalize_email(email)
        user = self.model(email=email, username=username,
                          first_name=first_name, **other_fields)
        user.set_password(password)
        user.save()
        return user
    

    最后添加设置:

    AUTH_USER_MODEL = "users.NewUser"
    

    您可以在 django officeil 文档中查找明确的详细信息

    【讨论】:

    • 我仍然想让用户使用他们的电子邮件登录,而不是用户名。在这种情况下,如果我正在重新建模模型,那么在这种情况下我应该放弃使用 AbstractUser 吗?
    • 我刚刚将其添加到答案中,希望您正在寻找什么
    • 谢谢。但我最终将用户名设置为视图和表单中的电子邮件地址。但是,我一定会记住您的解决方案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 2016-04-02
    • 2020-08-01
    相关资源
    最近更新 更多