保存表单时的 Django 完整性错误



我扩展了 Django 用户模型并添加了我自己的字段,目前正在注册期间填写这些字段。该表单似乎工作正常,除了保存之外,其他所有内容。

用这个来帮助我。

下面是用户模型的扩展:

class StudentProfile(models.Model):
    user = models.OneToOneField(User, null = True, related_name='user', on_delete=models.CASCADE)
    teacher = models.BooleanField(default = False)
    school = models.CharField(max_length = 50)
def create_StudentProfile(sender, **kwargs):
    if kwargs['created']:
        user_profile = StudentProfile.objects.create(user = kwargs['instance'])

post_save.connect(create_StudentProfile, sender = User)

这是我的表格:

class StudentRegistrationForm(UserCreationForm):
    email = forms.EmailField(required = True)
    school = forms.CharField(required = True)
    def __init__(self, *args, **kwargs):
        super(StudentRegistrationForm, self).__init__(*args, **kwargs)
        self.fields['username'].help_text = ''
        self.fields['password2'].help_text = ''

    class Meta:
        model = User
        fields = (
            'username',
            'first_name',
            'last_name',
            'email',
            'school',
            'password1',
            'password2'            
        )
    def save(self, commit = True):
        user = super(StudentRegistrationForm, self).save(commit = False)
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.email = self.cleaned_data['email']

        student_profile = StudentProfile(user = user, school = self.cleaned_data['school'])
        if commit:
            user.save()
            student_profile.save()
        return user, student_profile

以下是我的观点:

def registration(request):
    if request.method == 'POST':
        form = StudentRegistrationForm(request.POST)
        if form.is_valid():
            user, user_profile = form.save(commit = False)
            form.save()
            return render(request, 'accounts/home.html')
        else:
            args = {'form': form}
            return render(request, 'accounts/reg_form.html', args)
    else:
        form = StudentRegistrationForm()
        args = {'form': form}
        return render(request, 'accounts/reg_form.html', args)

这是我的回溯:

File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py" in execute
  337.         return Database.Cursor.execute(self, query, params)
The above exception (NOT NULL constraint failed: userprofile_studentprofile.user_id) was the direct cause of the following exception:
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  39.             response = get_response(request)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/wtreston/GDrive/LesRev/lesssonreview/userprofile/views.py" in registration
  13.             form.save()
File "/Users/wtreston/GDrive/LesRev/lesssonreview/userprofile/forms.py" in save
  41.             student_profile.save()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/base.py" in save
  796.                        force_update=force_update, update_fields=update_fields)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/base.py" in save_base
  824.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/base.py" in _save_table
  908.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/base.py" in _do_insert
  947.                                using=using, raw=raw)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  85.                 return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/query.py" in _insert
  1045.         return query.get_compiler(using=using).execute_sql(return_id)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1054.                 cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  79.             return super(CursorDebugWrapper, self).execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/utils.py" in __exit__
  94.                 six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/six.py" in reraise
  685.             raise value.with_traceback(tb)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py" in execute
  337.         return Database.Cursor.execute(self, query, params)
Exception Type: IntegrityError at /users/
Exception Value: NOT NULL constraint failed: userprofile_studentprofile.user_id

谢谢!

您必须

使用模型创建一个用户User然后您必须将此用户传递给StudentProfile因为它是您StudentProfile onetoone字段。

def save(self, request):
        form = StudentRegistrationForm(request.POST)
        user = User.objects.create(first_name=form.cleaned_data['first_name'],
                            last_name=form.cleaned_data['last_name'],
                            email=form.cleaned_data['email'],
                            username=form.cleaned_data['username'])
        user_profile = StudentProfile.objects.create(user=user,
                                                teacher=form.cleaned_data['teacher'],
                                                school=form.cleaned_data['school'])

        return user, student_profile

看起来 use 对象没有被保存,以便它可以存储其引用的学生配置文件模型。

这里有许多问题。

直接的问题是您在两个地方创建用户配置文件。你已注册了一个信号处理程序 - create_StudentProfile - 在创建用户时自动创建一个;但是,您还将在窗体的save方法中创建一个新方法。

您应该考虑是否真的需要该信号处理程序。如果您总是要通过此表单创建用户,则该处理程序是不必要的。

如果您决定需要信号,则需要重做保存方法以考虑它。像这样:

def save(self, commit=True):
    user = super(StudentRegistrationForm, self).save(commit = False)
    if commit:
        user.save()
        profile = user.userprofile
    else:
        profile = UserProfile(user=user)
    profile.school = self.cleaned_data['school']
    if commit:
        profile.save()
    return user, student_profile

您会注意到,无需设置电子邮件和名称,因为这些是通过超级通话中已有的表单完成的。

第二个问题是您在视图中调用了两次 save 方法。别这样。

    if form.is_valid():
        user, user_profile = form.save()
        return render(request, 'accounts/home.html')

最新更新