2017-06-12 49 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