IntegrityError at /users/signup NOT NULL 约束失败:users_user.username

IntegrityError at /users/signup NOT NULL constraint failed: users_user.username

我在做什么

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

错误图片

它只是把 IntegrityError 扔进了我的控制台。

IntegrityError at / NOT NULL contraint failed

我尝试解决的问题

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

源代码

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

  1. templates/users/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

请帮帮我!

错误提示您没有将用户名添加为数据 在您的 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 文档中查找明确的详细信息