【问题标题】:How to display a custom field only in change view (admin)如何仅在更改视图中显示自定义字段(管理员)
【发布时间】:2013-12-05 22:37:06
【问题描述】:

我是 Python 和 Django 的新手 :) 我需要一些帮助。

我想做什么:

我有一个模型页面,当有人尝试更新一个对象时,我需要添加一个自定义字段“消息”。

为什么?因为我正在建立一个修订系统。这个字段,只是对变化的解释。所以这个字段没有链接到Page(而是链接到另一个模型PageRevision)

经过一些研究,我设法将此字段添加到我的 admin.py 文件中的表单中,如下所示:

class PageAdminForm(forms.ModelForm):
    # custom field not backed by database
    message = forms.CharField(required=False)

    class Meta:
        model = Page

它正在工作,我的字段现在显示...但我不希望这个字段无处不在。就在有人尝试更新 Page 对象时。 我找到了这个答案different-fields-for-add-and-change-pages-in-admin,但它对我不起作用,因为它是一个自定义字段(我认为)。

我在 admin.py 中的其余代码:

class PageAdmin(admin.ModelAdmin):
    form = PageAdminForm
    fields = ["title", "weight", "description", "message"]
    list_display = ["title", "weight", "description"]
    list_filter = ["updated_at"]

    def get_form(self, request, obj=None, **kwargs):
        if obj is None:
            # not working ?
            kwargs['exclude'] = ['message']
        # else:
        #     kwargs['exclude'] = ['message']
        return super(PageAdmin, self).get_form(request, obj, **kwargs)

    def save_model(self, request, obj, form, change):
        if not obj.id:
            obj.author = request.user
        obj.modified_by = request.user
        wiki_page = obj.save()

        # save page in revision table
        revision = PageRevision(change=change, obj=wiki_page,
                            request=request)
        # retrieve value in the custom field
        revision.message = form.cleaned_data['message']
        revision.save()

def get_form 不排除我的自定义消息字段,因为我认为它不知道存在。如果我输入另一个字段,例如标题,它就可以了。 那么如何从添加视图中排除自定义字段呢?

谢谢:)

【问题讨论】:

    标签: django django-admin


    【解决方案1】:

    我只是偶然发现了同样的问题,因为它出现在第一个搜索结果中,所以我想为不想使用自定义表单的人添加这个其他解决方案。

    您可以覆盖管理类的 get_fields 方法以从“添加”页面中删除自定义字段。

    def get_fields(self, request, obj=None):
        fields = list(super().get_fields(request, obj=obj))
        if obj is None:
            fields.remove("message")
        return fields
    

    【讨论】:

    • 我不确定为什么这个答案被否决;它对我来说效果很好!
    【解决方案2】:

    您是对的,它不会以这种方式工作,因为“消息”不是在 Page 模型上找到的字段,并且 ModelAdmin 类将忽略排除。您可以通过多种方式实现这一目标,但我认为最好的方法是:

    class PageAdmin(admin.ModelAmin):
        change_form = PageAdminForm
    
        ...
    
        def get_form(self, request, obj=None, **kwargs):
           if obj is not None:
              kwargs['form'] = self.change_form
    
           return super(UserAdmin, self).get_form(request, obj, **defaults)
    

    在这里,django 将在添加页面时使用自动生成的 ModelForm,在编辑页面时使用自定义表单。 Django 本身在添加和更改用户时使用类似的技术来显示不同的表单:

    https://github.com/django/django/blob/stable/1.6.x/django/contrib/auth/admin.py(有趣的部分在第 68 行)

    【讨论】:

    • 谢谢! +1 链接非常有趣。现在我有一个新错误“NoneType”对象仅在我处于更改视图时不可迭代。我今晚会调查此事。
    • 好的,这是导致错误“get_fieldsets”的另一种方法...我必须从 PageAdmin 中删除行 fields=[...] 并在我的模型上添加 editable=false 以仅显示我想要的领域。 (因为消息字段在添加表单中导致错误,因为它不再找到)
    猜你喜欢
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    相关资源
    最近更新 更多