2017-06-12 68 views
0

我扩展了Django用户模型并添加了自己的字段,目前正在注册时填写这些字段。该表格似乎正在正常工作,除了保存以外的所有内容。我使用this来帮助我。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 

谢谢!

回答

1

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

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 
+0

在尝试你的方法,我得到一个错误说“保存()失踪1个人需要的位置参数:‘请求’”在我在行意见“的用户,user_profile = form.save()” – wtreston

+0

使用'用户,user_profile = form.save(request)' –

+0

得到它的工作。将其更改为self.cleaned_data并且它可以工作! – wtreston

0

它看起来像使用对象没有被保存,以便它可以存储其引用StudentProfile模型。

0

这里有很多问题。

直接的问题是你在两个地方创建UserProfile。您已经注册了一个信号处理程序 - 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') 
+0

我已经删除了信号处理程序并更改了我的视图中的代码。py,但是我仍然得到相同的错误:“IntegrityError at/users/ NOT NULL约束失败:userprofile_studentprofile.user_id”。用户正在创建并添加到数据库,但是,添加的字段(如学校)未被保存。 – wtreston

+0

你不应该做这两件事,他们是替代品。您仍然需要在某处创建配置文件。 –

+0

我很困惑...对不起。根据我对你写的内容的理解,信号处理程序创建了StudentProfile,并在Forms保存方法中创建了一个。因为我只会通过此表单添加用户,所以我删除了信号处理程序,并保留了原来的保存方法。然后我在我看来更新了保存方法。我不明白你是什么意思,我不应该做这两件事?谢谢 – wtreston