2012-01-29 47 views
1

我有一個註冊表單,當用戶在其中輸入有效的註冊數據時,它將用戶登錄並將用戶重定向到另一表單以輸入更多數據。這種新的形式包含有關用戶的更多數據,並使用下面的ModelForm類創建:在使用ModelForm創建的表單對象中設置用戶字段

class UserProfileAddForm(ModelForm): 
    class Meta: 
     model = UserProfile 
     exclude = ('user') 

和用戶配置模型的樣子:

class UserProfile(models.Model): 
    GRADE_YEAR_CHOICES = (
     ('FR', 'Freshman'), 
     ('SO', 'Sophomore'), 
     ('JR', 'Junior'), 
     ('SR', 'Senior'), 
     ('GR', 'Graduate') 
    ) 

    school = models.CharField(max_length=64) 
    grade_year = models.CharField(max_length=2, choices=GRADE_YEAR_CHOICES) 
    gpa = models.DecimalField(decimal_places=2, max_digits=6, blank=True, null=True) 
    user = models.ForeignKey(User, unique=True) 

當用戶字段是一個ForeignKey到Django的User對象。我很難將用戶字段設置爲發出請求的用戶。以下是我在我的views.py試圖

第一次嘗試:

def more(request): 
    if request.method == 'POST': 
     form = UserProfileAddForm(request.POST) 
     if form.is_valid(): 
      form.save(commit=False) 
      form.user = request.user 
      form.save() 
      return HttpResponseRedirect('/register/success/') 
    else: 
     form = UserProfileAddForm() 
     variables = RequestContext(request, { 
      'form': form 

第二次嘗試:

def more(request): 
    if request.method == 'POST': 
     form = UserProfileAddForm(request.POST) 
     if form.is_valid(): 
      form.save(commit=False) 
      form.user = User.objects.filter(username=request.user) 
      form.save() 
      return HttpResponseRedirect('/register/success/') 
    else: 
     form = UserProfileAddForm() 
     variables = RequestContext(request, { 
      'form': form 
     }) 
     return render_to_response('registration/more.html', variables) 

無論哪種方式,我嘗試它似乎不救數據到數據庫。然而,它會將我重定向到成功頁面,就像它成功保存一樣。

回答

2

form.save()返回正在保存的模型的一個實例。在那裏你需要設置用戶,然後保存該實例。

profile = form.save(commit=False) 
profile.user = request.user 
profile.save() 

注意,正從基於的request.user值的數據庫的用戶是沒有意義的,因爲request.user已經是正確的用戶對象。

+0

完美運作。所以我理解它們之間的區別,在'form'對象中,你實際上不能改變實例的值,但是在'profile'對象中你可以?爲什麼我不能直接執行'form.user = request.user'? – 2012-01-29 21:33:00

+1

@NicYoung,Django [表單對象包含一個Field對象的集合](https://docs.djangoproject.com/en/dev/topics/forms/#form-objects),你可以[在這裏閱讀](https ://docs.djangoproject.com/en/dev/ref/forms/fields/)與你試圖修改的對象沒有任何關係。 'form.save()'爲你保存的對象創建一個新的「實例」,這就是你可以修改的那個。 – Dirk 2012-01-29 21:40:22

+0

@Dirk感謝您的澄清。所以實際上實例化對象使其可以修改。這是我必須習慣的。 – 2012-01-29 21:46:24

1

我的建議是,你在做第二次嘗試這種變化:

 with_profile = form.save(commit=False) 
     with_profile.user = request.user 
     form.save() 
     ... 

問題是,您要添加user屬性form對象insteat到form.instance對象。

編輯

當我第一次公佈答案,我mistaked用戶assignement。 @Dirk在下面評論它,現在已修復。謝謝@Dirk。問題是一個查詢集被分配到with_profile.user,並且具有單個模型。

+0

第一次嘗試的修改會更好,因爲它消除了'request.user'中已有的一段數據在數據庫中的運行。另外,第二次嘗試不會返回QuerySet而不是用戶對象? – Dirk 2012-01-29 21:12:08

+0

@Dirk,真的,我非常感謝!我修復它。 – danihp 2012-01-29 21:19:29

+0

我想我很難理解'form'對象和'instance'對象之間的區別。我已經改變了你的建議,現在我得到了一個Integerity Error:'gradebook_userprofile.user_id可能不是NULL',所以它似乎沒有在實例對象上設置用戶字段。 – 2012-01-29 21:20:22

0

那麼,你需要了解的是,當你在你做 即情況

profile = form.save(commit =False) 

當你保存模型對象不保存任何多對多的關係你得到的模型實例。保存模型對象後需要執行的操作。通過這樣做,

form.save_m2m() 

所以,只需在保存模型對象後添加最後一段代碼即可。

相關問題