2010-07-21 58 views
1

摘要:Django的配置文件創建自定義/編輯的ModelForm不保存正確

u = self.instance.user 

def save(self, *args, **kwargs): 
    u = self.instance.user 
    u.first_name = self.cleaned_data['first_name'] 
    u.last_name = self.cleaned_data['last_name'] 
    u.save() 
    return super(ProfileForm, self).save(*args, **kwargs) 

因爲self.instance不存在導致問題。但是,這是它在其他例子中的工作方式,它似乎起作用。我錯過了什麼?

閱讀更多的信息 - >

我同時使用Django的登記和Django的配置文件。爲了達到它的目的,我沒有向profile模型(擴展User的那個)添加額外的字段。到目前爲止,它看起來像這樣:

class sumaConnectUser(models.Model): 

    user = models.ForeignKey(User) 

    def __unicode__(self): 
     return self.user.first_name + " " + self.user.last_name 

    def get_absolute_url(self): 
     return ('profiles_profile_detail',(), { 'username': self.user.username }) 
    get_absolute_url = models.permalink(get_absolute_url) 

我的理解是,截至目前,我的用戶「個人資料」應該只包括附帶contrib.auth模型用戶的字段。 (姓,名等)

在我的urls.py,我在自定義表單傳遞了的profiles-

(r'^profiles/edit', 'profiles.views.edit_profile', {'form_class': ProfileForm, }), 
(r'^profiles/create', 'profiles.views.create_profile', {'form_class': ProfileForm, }),     
(r'^profiles/', include('profiles.urls')), 

最後的創建和編輯,這是我的個人資料形式 -

from suma.sumaconnect.models import sumaConnectUser 
from django import forms 
from django.contrib.auth.models import User 

class ProfileForm(forms.ModelForm): 
def __init__(self, *args, **kwargs): 
    super(ProfileForm, self).__init__(*args, **kwargs) 
    try: 
     self.fields['first_name'].initial = self.instance.user.first_name 
     self.fields['last_name'].initial = self.instance.user.last_name 
    except User.DoesNotExist: 
     pass 

first_name = forms.CharField(label="First Name") 
last_name = forms.CharField(label="Last Name") 

class Meta: 
    exclude = ('user',) 
    model = sumaConnectUser 

def save(self, *args, **kwargs): 
    u = self.instance.user 
    u.first_name = self.cleaned_data['first_name'] 
    u.last_name = self.cleaned_data['last_name'] 
    u.save() 
    return super(ProfileForm, self).save(*args, **kwargs) 

我的目標是允許用戶編輯他們的名字和姓氏作爲個人資料編輯的一部分,但不是他們的用戶名和密碼。

我想和

u = User.objects.get(user = self.cleaned_data['username']) 

更換

u = self.instance.user 

但這需要我包括我不想在頁面上顯示用戶名= forms.CharField。據我所知,當我進入創建配置文件或編輯配置文件頁面時,我應該自動編輯與我登錄的用戶相關的配置文件。

當我創建或編輯用戶頁面時,用戶模型已經存在,但配置文件不存在。這是問題的原因嗎?我認爲我誤解了一些重要的東西,我非常感謝任何關於我出錯的地方。謝謝!

回答

0

如果您願意,您可以複製字段,然後像上面那樣對它們進行雙重更新,但這不是配置文件的用途。它應該處理不在原始auth.User中的字段,因爲您不需要直接編輯該模型。你在上面提到了「擴展用戶」 - 你實際上不是從auth.User繼承的,對嗎?我高度不建議這樣做。

更新:

this reference material。它使用與您在配置文件中進行用戶更新相同的語法。

更新2:

的例子是編輯個人資料,不能創建個人資料。查看profile.views中的代碼。create_profile:

if request.method == 'POST': 
    form = form_class(data=request.POST, files=request.FILES) 
    if form.is_valid(): 
     profile_obj = form.save(commit=False) 
     profile_obj.user = request.user 
     profile_obj.save() 

所以保存表單第一,然後設置用戶,然後保存配置。

這意味着你不能在form.save設置用戶值,你需要做的是在配置文件中的model.save:

# in sumaConnectUser: 

from django.db.models.base import ObjectDoesNotExist 
class sumaConnectUser(models.Model): 
    ... 
    def save(self, *args, **kwargs): 
    s = super(sumaConnectUser,self).save(*args, **kwargs) 
    try: 
     u = s.user 
     u.first_name = self.first_name 
     u.last_name = self.last_name 
     u.save() 
    except ObjectDoesNotExist: 
     pass 
    return s 

基本上,通過查看profile.views代碼.create_profile,我們是積極最終調用保存在配置文件它已經設置user。這可能不是第一次,所以我們需要陷入困境並忘掉它。因爲最終,它會被調用並觸發我們的保存到用戶代碼。結果是,無論您將來如何爲此用戶配置文件創建任何表單,它總是會保存回基礎用戶。

+0

我沒有從auth.User中插入,而是通過配置文件模型中的ForeignKey字段進行擴展。我知道你說過我不應該雙重更新任何東西,但對我來說並不像我。我的意思是,我想要的只是讓用戶能夠編輯auth.User模型的first_name和last_name屬性。因此,我在表單中包含了兩個字段。然後,我將它們分配給用戶的相應字段,並在保存整個配置文件之前進行保存。當你說使用super.save時,你是否真的將「super.save()」作爲保存函數的第一行? – dpetters 2010-07-21 17:00:00

+0

對不起,正在寫速記。我的意思是你寫的超級電話。在這個特殊情況下,恕我直言,沒有任何錯誤的複製領域,否則你需要有兩種形式和/或編輯auth.User。 – eruciform 2010-07-21 17:05:03

+0

所以我試着把「profile = super(ProfileForm,self).save(* args,** kwargs)」放在最上面,然後在函數的最底部放上「return profile」,但我仍然得到一個「DoesNotExist at/profiles/create「錯誤在」u = self.instance.user「行。甚至不存在self.instance。這是否意味着我需要第一次實例化配置文件? – dpetters 2010-07-21 17:44:32