2011-11-01 28 views
2

我跟隨Beginning Django E-Commerce,但我發現有關用戶配置文件的部分有點令人困惑。基本上,我有一個抽象類是這樣的:Django用戶配置文件中的必填字段

class BaseOrderInfo(models.Model): 
    class Meta: 
    abstract = True 
    # a bunch of fields follow 
    shipping_name = models.CharField() 
    # etc 

此之後,用戶配置類繼承BaseOrderInfo:

class UserProfile(BaseOrderInfo): 
    user = models.ForeignKey(User, unique = True) 
    # Possibly other methods or fields here 

最後,有一個檢索方法,正如它的名字所暗示的,檢索用戶配置文件(如果該用戶配置文件不存在,它會創建一個針對該用戶對象):

def retrieve(request): 
    try: 
    profile = request.user.get_profile() 
    except UserProfile.DoesNotExist: 
    profile = UserProfile(user=request.user) 
    profile.save() 
    return profile 

好吧,我的問題是:怎麼可能保存該用戶配置instanc e在檢索方法中,只需添加一個User實例,因爲UserProfile從BaseOrderInfo類繼承了相當多的其他字段?據我所知,Model和ModelForm默認創建必需的字段。

感謝

回答

1

保存表單時,Django不驗證模型。 (請參閱Validating Objects上的文檔)。如果您在保存之前明確地呼叫profile.full_clean(),那麼您將看到驗證錯誤。

如果沒有指定所需的外鍵,那麼您將得到一個數據庫IntegrityError。其他必填字段由Django進行驗證,而不是數據庫。如果Django不驗證模型,那麼在將數據庫中的空字符串保存到CharField時不會有任何錯誤。

+0

哦,現在我明白了。 save()不會調用full_clean()。但是,https://docs.djangoproject。com/en/dev/ref/models/instances /#當你保存時發生什麼 - 描述了保存的過程,並指出了4和5看起來應該在將SQL語句插入數據庫之前進行驗證。你能澄清那部分嗎? –

+0

預處理和準備與驗證不同,儘管它們可能引發驗證錯誤,例如@Chris建議將'datetime'空。當'UserProfile'實例中的CharField被要求爲數據庫準備值時,它會返回默認的'u'「'。它沒有被要求驗證價值。 – Alasdair

+0

太好了。非常感謝。 –

1

如果UserProfile有任何必填字段,你需要展示一個形式向用戶首先收集數據。只要您需要訪問用戶個人資料數據,但確定個人資料尚不存在,您可以將其整合到您的註冊表單中,或者僅提供一份單獨的個人資料表。

+0

感謝您的回答。在這種情況下,我寫了書中的類。 UserProfile沒有任何更多的字段,但是,BaseOrderInfo有相當多的字段。作爲models.Model的子類中的字段默認是必需的,BaseOrderInfo不包含任何使用「required = False」的字段,在我看來,profile.save()不應該工作。 –

+0

似乎你不瞭解繼承。 'BaseOrderInfo'是一個抽象類;它本身並不存在,而只是提供一個模板。當你讓'UserProfile'繼承它時,'UserProfile'包含所有這些字段,就像你簡單地把它們放在'UserProfile'類本身一樣。相同的說明適用。如果有必填字段,則必須提供用於輸入該數據的表單。 –

+0

也許我沒有正確表達自己。我理解繼承部分,但我想知道爲什麼在保存UserProfile的實例時爲什麼從BaseOrderInfo繼承的UserProfile字段被'忽略',假設默認情況下這些字段是必需的。我認爲@Alasdair指出解決方案:save()不驗證。 –

相關問題