2013-03-11 27 views
2

上更新我想不通爲什麼clean_field()方法不會被調用了一種直列形式是在一個管理視圖更新。我的代碼似乎直線前進(見下文簡介)。Django的 - clean_field()不會被調用的管理內嵌形式

當我修改通過管理界面(http://admin/..../primary/1/)主形式,如預期,我看到:

  • Admin.PrimaryAdminForm.clean_myfield()稱爲
  • Admin.PrimaryAdminForm.clean()稱爲
  • Model.Primary.clean()稱爲

然而,當我修改Primary作爲視爲對成員的管理視圖(http://admin/..../membership/1/)一個內聯,我ONL Y見:

  • Model.Primary.clean()稱爲

我試圖放置「高清clean_myfield(個體經營):」在以下位置的方法,但不能看到它您可以通過執行內聯成員主要形式:

  • Model.Primary.clean_myfield
  • Admin.PrimaryAdmin.clean_myfield
  • Admin.PrimaryAdminForm.clea n_myfield
  • Admin.PrimaryAdminInline.clean_myfield

有沒有別的地方這clean_myfield代碼應該放在哪裏?

我已閱讀(並重新閱讀)[形式和字段驗證] [docs.djangoproject.com/en/dev/ref/forms/validation/#form-and-field-validation]上的Django文檔,它給出了覆蓋面很大,但內聯驗證沒有任何內容。我也看到了docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-custom-validation-to-the-admin,但對於內聯特定的驗證沒有幫助。有沒有其他文件?

--->回答奧斯丁提供了一個文檔參考:「如果沒有指定」(見他的鏈接),這意味着答案。我說這個話題request to improve的文件。

經過進一步的實驗,我發現一個解決方法通過將代碼在Model.Primary.clean()方法:

def clean(self): 
    data = self.myfield 
    data += "_extra" # not actual cleaning code 
    self.myfield = data 

所以問題仍然存在:爲什麼Model.clean()似乎是隻有放置管理內聯表單驗證的地方,而不是在clean_myfield(self)方法中?

--->奧斯汀回答。我需要添加form = PrimaryAdminForm到PrimaryInline。有了這個添加,PrimaryAdminForm.clean_myfield(self)會在MembershipInform表單上更新PrimaryInline myfield時調用。由於添加了表單引用,代碼排序已更新。

代碼簡介:

沒有forms.py文件 - 所有型號都通過管理界面更新

models.py:

class Membership(models.Model): 
    name = models.CharField(max_length=NAME_LENGTH, 
     null=True, blank=True, verbose_name="Membership Name Tag", 
     help_text="Name of membership") 

class Primary(models.Model): 
    user = models.OneToOneField(User, verbose_name="User Name") 
    membership = models.OneToOneField(Membership, verbose_name="Membership Name") 
    myfield = models.CharField("My Field", max_length=20, null=True, blank=True) 


    # clean method altered as in Update comment 
    # Why must this be here? Why not in clean_myfield(self) 
    def clean(self): 
     data = self.myfield 
     data += "_extra" # not actual cleaning code 
     self.myfield = data 

admin.py :

class MembershipAdminForm(ModelForm): 
    class Meta: 
     model = Membership 

class PrimaryAdminForm(ModelForm): 
    class Meta: 
     model = Primary 

    def clean_myfield(self): 
     data = self.cleaned_data['myfield'] 
     data += "_extra" # not actual cleaning code 
     return unicode(data) 

    def clean(self): 
     cleaned_data = super(PrimaryAdminForm, self).clean() 
     # not actual cleaning code 
     return cleaned_data 

# EDIT2: Moved PrimaryInline so it's defined after PrimaryAdminForm 
class PrimaryInline(admin.StackedInline): 
    model = Primary 
    form = PrimaryAdminForm #EDIT2 as recommended by Austin 
    raw_id_fields = ['user'] 
    verbose_name_plural = 'Primary Member' 
    fieldsets = ((None, {'classes': ('mbship',), 
         'fields': ('user', 'myfield')}),) 

class MembershipAdmin(admin.ModelAdmin): 
    form = MembershipAdminForm 

    # inlines 
    inlines = [PrimaryInline, ] 

    fieldsets = ((None, {'classes': ('mbship',), 
         'fields': ('name'), }),) 

class PrimaryAdmin(admin.ModelAdmin): 
    form = PrimaryAdminForm 
    list_display = ('__unicode__', 'user', 'status', 'date_used') 
    search_fields = ['user__first_name', 'user__last_name', 'user__email'] 

    fieldsets = ((None, {'classes': ('mbship',), 
         'fields': ('user', 'membership', 'myfield'), }),) 

    def clean_myfield(self): 
     data = self.cleaned_data['myfield'] 
     data += "_extra" # not actual cleaning code 
     return unicode(data) 
+0

更新爲反映Austin的答案。 – ChrisFreeman 2013-03-12 13:37:01

回答

7

驗證發生在ModelForm對象上,而不是ModelAdmin對象。如果你想覆蓋任何干淨的方法,那麼你必須爲每個需要的模型創建自己的ModelForm後代。

在您的示例中,PrimaryInline類未指定formIf not specified,使用的表格將是ModelForm,它沒有任何自定義清理方法。

試試這個:

class PrimaryInline(admin.StackedInline): 
    # ... existing code ... 
    form = PrimaryAdminForm 

現在,這將使用自定義PrimaryAdminForm與相關clean()方法。

+0

謝謝奧斯汀!我希望django文檔有一個例子,顯示爲同一個類定義指定的模型和表單。我請求了文檔更新。對不起,我很樂意提高你的答案(我會在某天回來做)。 – ChrisFreeman 2013-03-12 13:36:23

+0

終於!足夠的分數來投票! (2年半後) – ChrisFreeman 2015-09-14 15:29:56