如何仅在更改视图中显示自定义字段(admin)

时间:2013-12-05 22:37:07

标签: django django-admin

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

我想做什么:

我有一个模型 Page ,当有人试图更新一个对象时,我需要添加一个自定义字段“message”。

为什么呢?因为我正在建立一个修订系统。这个领域,它只是对变化的解释。所以这个字段没有链接到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 不排除我的自定义消息字段,因为我认为它不知道是否存在。如果我把另一个像标题的字段,它的工作原理。 那么如何从添加视图中排除自定义字段?

谢谢:)

2 个答案:

答案 0 :(得分:5)

你是对的,它不会以这种方式工作,因为'message'不是在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)

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

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

答案 1 :(得分:-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