【问题标题】:Custom ModelAdmin: allow admin class validation to ignore fields in a fieldset?自定义 ModelAdmin:允许管理类验证忽略字段集中的字段?
【发布时间】:2011-11-15 17:04:14
【问题描述】:

我正在编写一个小应用程序,以允许 django 管理员更改列表中的 AddThis 共享字段,以允许用户共享他们当前正在编辑的对象(以及查看共享计数):

以一个简单的 BlogEntry 为例,我创建了一个自定义的 ModelAdmin:

class AddThisAdmin(admin.ModelAdmin):
    addthis_config = {
        'title_field' : None,
        'description_field' : None, 
        'url_field' : None,
        'image_field' : None,
    }

    def get_form(self, request, obj=None, *args, **kwargs):
        metaform = super(AddThisAdmin, self).get_form(request, obj, **kwargs)
        if obj:
            # Grab users config and find the fields they specified ...
            metaform.base_fields['add_this'] = AddThisField(self.add_this)
        return metaform

在用户 BlogEntryAdmin 中继承如下:

class BlogEntryAdmin(admin.ModelAdmin, AddThisAdmin):
    addthis_config = {
        'title_field' : 'blog_title',
        'description_field' : 'blurb',
    }

addthis_config 允许用户在其 BlogEntry 对象中指定字段,从哪里提取 AddThis 中使用的标题/描述/url 和图像。在我决定在 BlogEntryAdmin 中使用自定义字段集之前,这一切都非常有效:

class BlogEntryAdmin(admin.ModelAdmin, AddThisAdmin):
    addthis_config = {
        'title_field' : 'blog_title',
        'description_field' : 'blurb',
    }
    fieldsets = [{ ... }]

'BlogEntry.fieldsets0['fields']' 指的是表单中缺少的字段 'add_this'。

我知道这是因为 django 管理员在实际实例化之前对 BlogEntryAdmin 类上的字段集 (django.contrib.admin.validation) 进行了验证(并插入了我的自定义字段)。

tldr :有没有办法告诉django.contrib.admin.validation 忽略字段集中的字段?

【问题讨论】:

  • 顺便说一句,您是否有理由从ModelAdminAddThisAdmin 继承而不仅仅是AddThisAdminBlogEntry.get_form() 不会解析为ModelAdminget_form,而不是您自定义的吗?
  • 我上面的评论可能完全错误。已经很晚了,当我比现在清醒得多时,我可能会弄错 MRO ;)
  • 不,你是对的,我认为不需要多重继承!

标签: django django-admin django-forms


【解决方案1】:

典型的方法是提供像AddThisAdminForm 这样具有必填字段的基本表单,并让其他ModelAdmin 的表单继承自该表单。看起来您正试图避免这种情况,并将字段自动插入到正在使用的任何形式中。如果您坚持采用这种方法,则以下内容应该会更好:

def get_form(self, request, obj=None, **kwargs):
    ModelForm = super(AddThisAdmin, self).get_form(request, obj, **kwargs)
    class AddThisForm(ModelForm):
        add_this = AddThisField(self.add_this)

    return AddThisForm

【讨论】:

  • 是的,我想设置它,以便在从 AddThisModelAdmin 继承后自动插入额外的字段,使其尽可能可重用。以上似乎仍然导致相同的错误。据我所知,django.admin.validator 在任何 ModelAdmin 被实例化之前被调用,它使用一些类方法来执行验证,这意味着 get_form 直到这个过程之后才被调用?不过我不是 100% 确定
  • 我将此标记为已接受,因为我最终按照您在答案第一部分中的建议进行了操作:创建了一个 AddThisForm ,它添加了一个字段并有条件地隐藏了整行(使用带有一些javascript) 如果一个对象没有被保存。感谢您的帮助
【解决方案2】:

它没有记录,但您可以使用get_fieldsets 方法来定义您的字段集。例如,看看 Django 在添加新用户时如何更改 UserAdmin 中的字段集。

我没有对此进行测试,但我相信它会避免fieldset 验证。

【讨论】:

  • 我注意到了这一点,但我正在尝试编写它,以便我可以简单地从 AddThisModelAdmin 继承而不必做任何其他事情(以便将来重新使用)。使用此方法(据我了解?)我需要在我想使用该字段的每个模型管理员中覆盖 get_fieldsets 方法(以及继承 AddThisModelAdmin)
  • 您需要在可重用性与实现它所需的魔力/丑陋之间取得平衡。猴子补丁validate?如果您想保留 ModelAdmin 验证的其余部分,可能会重复很多。 AddThisAdmin 上的一些元类魔法删除了 fieldset 属性并添加了替换 get_fieldsets 方法?一开始很棘手,然后当您尝试处理实现了get_fieldsetsModelAdmin 时更加棘手。祝你好运。
  • 这是一个很好的观点。我可能过度考虑了整个事情的可重用性。使用 javascript 提供覆盖的模板并通过 modeladmin change_view 或其他方式提供变量可能更容易。感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 2016-03-05
  • 2014-02-02
  • 2011-04-29
  • 1970-01-01
  • 1970-01-01
  • 2019-06-26
  • 1970-01-01
  • 2018-08-05
相关资源
最近更新 更多