gpt4 book ai didi

Django - clean_field() 没有被调用来更新管理内联表单

转载 作者:行者123 更新时间:2023-12-01 08:33:15 25 4
gpt4 key购买 nike

我不明白为什么没有为在管理 View 上更新的内联表单调用 clean_field() 方法。我的代码看起来很简单(见下面的概要)。

当我通过管理界面 (http://admin/..../primary/1/) 修改主表单时,正如预期的那样,我看到:

  • Admin.PrimaryAdminForm.clean_myfield() 调用
  • Admin.PrimaryAdminForm.clean() 调用
  • Model.Primary.clean() 调用

但是,当我在成员资格 (http://admin/..../membership/1/) 的管理 View 中将主节点修改为内联时,我只看到:

  • Model.Primary.clean() 调用

我已尝试将“def clean_myfield(self):”方法放置在以下位置,但看不到它从内联的 Membership 主要表单中执行:

  • Model.Primary.clean_myfield
  • Admin.PrimaryAdmin.clean_myfield
  • Admin.PrimaryAdminForm.clean_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,但对内联特定验证没有帮助。是否有其他相关文档?

---> Answered by Austin 提供了一个文档引用:“如果未指定”(请参阅​​他的链接),这意味着答案。我添加了 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) 在成员(member)表单上更新 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)

最佳答案

验证发生在 ModelForm 对象上,而不是 ModelAdmin 对象上。如果您想覆盖任何干净的方法,那么您必须为每个所需的模型创建自己的 ModelForm 后代。

在您的示例中,PrimaryInline 类没有指定 formIf not specified ,使用的表单将是一个 ModelForm,它没有任何自定义清理方法。

试试这个:

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

现在这将使用您的自定义 PrimaryAdminForm 和关联的 clean() 方法。

关于Django - clean_field() 没有被调用来更新管理内联表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15330490/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com