2012-08-17 51 views
1

我想創建一個「更新用戶的個人資料」頁面,讓用戶修改自己的個人資料,所以我想出了以下型號:Django表單問題與用戶配置

class Profile(models.Model): 
    user = models.OneToOneField(User) 

    nick_name = models.CharField(blank=True,max_length=100) 
    school = models.CharField(blank=True,max_length=100) 
    motto = models.CharField(blank=True,max_length=100) 

class ProfileForm(ModelForm): 
    class Meta: 
     model = Profile 

而我的觀點被設計成:

@login_required 
def update_profile_view(request): 
    if request.method == 'POST': 
     user = request.user 
     try: 
      profile = user.get_profile() 
     except Exception: 
      profile = Profile.objects.create(user=user) 
     form = ProfileForm(request.POST) 
     if form.is_valid(): 
      cd = form.cleaned_data 
      profile.nick_name = cd['nick_name'] 
      profile.school = cd['school'] 
      profile.motto = cd['motto'] 
      profile.save() 
      return HttpResponseRedirect('/main_page/') 
    else: 
     form = ProfileForm() 
    return render(request, 'update_profile.html', {'form':form}) 

用戶和配置文件之間的關係顯然是1to1,並與請求我可以確定當前的用戶。所以表單的用戶字段不需要填寫。不幸的是,這無法通過「form.is_valid()」測試。在調用「is_valid」之前,似乎很難修改表單。爲了簡單起見,我不想創建自己的Form類,也不想編寫自定義的表單驗證。有沒有其他解決問題的方法?

+0

什麼是實際的錯誤信息/追蹤?您可以嘗試使用ProfileForm(request.POST,instance = profile)實例化表單... – Jingo 2012-08-17 13:36:29

+0

非常類似的問題與有用的答案在這裏:[Django,用ModelForm更新用戶配置文件](http://stackoverflow.com/問題/ 1823588/django的更新管理一個用戶簡檔上帶有一個-的ModelForm)。 – dgel 2012-08-17 13:39:03

回答

2

你的觀點可以大大簡化:

@login_required 
def update_profile_view(request): 
    try: 
     profile = Profile.objects.get(user=request.user) 
    except Profile.DoesNotExist: 
     profile = None 

    form = ProfileForm(request.POST or None, instance=profile) 

    if request.method == 'POST':    
     if form.is_valid(): 
      form.save() 
      return HttpResponseRedirect('/main_page/') 
    return render(request, 'update_profile.html', {'form':form}) 

有沒有需要手動分配很喜歡現在做的領域。 Django ORM知道如何自動執行插入與更新。因此,如果您只是將ProfileForm作爲Profile的一個實例,它就知道要進行更新。如果沒有配置文件的實例,它將執行插入操作。

現在,如果您想在用戶界面中將用戶分配爲透明,則需要從表單中排除user字段並自行分配。有幾種不同的方法可以做到這一點。

我也建議在您的重定向中使用reverse,這樣您就沒有硬編碼路徑。

+0

不錯,但是,要小心,在GET情況下表單不會被初始化。你應該把'form = ...'移到第一行。 – danihp 2012-08-17 13:39:10

+0

謝謝老兄。我的咖啡尚未投入使用。 – Brandon 2012-08-17 13:43:49

0

您可以在表單的init方法(self.fields ['user']。required = False)中將用戶字段的值設置爲不需要,或者將用戶設置爲不可編輯模式(editable = False) 。

在您看來的方法,調用配置= form.save(提交= FALSE),然後做profile.user = your_user和profile.save()

您不必手動應用清理數據自從ModelForm完成後,該配置文件就完成了這個配置

2

你有basicly兩種選擇:ProfileForm的

1修改:

class ProfileForm(ModelForm): 
     class Meta: 
      model = Profileclass 
      exclude = ('user',) 

2更改此行,如下所示:

form = ProfileForm(request.POST, instance=profile) 
if form.is_valid(): 
    updated_profile = form.save()