如何隐藏 django-admin 中的某些字段?

Posted

技术标签:

【中文标题】如何隐藏 django-admin 中的某些字段?【英文标题】:How to hide some fields in django-admin? 【发布时间】:2012-05-07 00:54:39 【问题描述】:
class Book(models.Model):
    title = models.CharField(..., null=True)
    type = models.CharField(...)
    author = models.CharField(...)

我在 models.py 中有一个简单的类。在管理员中,当保存的书的类型为 1 时,我想隐藏书名(在书详细信息表单中)。 如何以最简单的方式做到这一点?

【问题讨论】:

您可以创建方法 Book.get_title_or_nothing 并在 BookAdmin 中使用它来显示它 好的,谢谢,你能给我举个例子如何在 BookAdmin 中使用它吗?因为我大致知道这个想法,但不完全知道,我应该使用哪个对象,这个函数应该返回什么。 问题是如何在admin中获取BookInline()类定义中的对象类型? 为什么要隐藏它?避免它被修改,或提交?或者只是意味着在这种情况下标题是无用的,因此应该被忽略? 在某些情况下无用,给用户造成混乱。 【参考方案1】:

你要在你的模块中创建admin.py(可能是book

class BookAdmin(admin.ModelAdmin):
    list_display = ("pk", "get_title_or_nothing")

书籍类中:

class Book:
    ...
    def get_title_or_nothing(self):
        if self.type == WEIRD_TYPE:
            return ""
        return self.title

更新:

class BookAdmin(admin.ModelAdmin):
    list_display = ("pk", "get_title_or_nothing")

    def get_form(self, request, obj=None, **kwargs):
        if obj.type == "1":
            self.exclude = ("title", )
        form = super(BookAdmin, self).get_form(request, obj, **kwargs)
        return form

【讨论】:

好的,谢谢,但是当我把它放在 BookInline 中时,我遇到了错误:表单中缺少 get_title_or_nothing'。你有什么想法吗?类BookInline(StackedInline):模型=书籍字段=('get_title_or_nothing') 重点是我需要隐藏表单的字段,而不是列表中的值。如果此对象的其他字段的值为 1,如何从 editable=True 更改为 editable=False。 是的,谢谢,用 BookAdmin 类没问题,但是 BookInline 呢?例如在哪里AuthorAdmin(admin.ModelAdmin): inlines = [BookInline,] 以及如何隐藏BookInline的字段?也许 get_formset()?你有什么想法吗:)? 在这种情况下,我不会使用 django-admin,而是创建自己的 真的,这种情况下不能用django-admin吗?【参考方案2】:

Django > 1.8 可以directly set the fields to be excluded in admin

 class PostCodesAdmin(admin.ModelAdmin):
      exclude = ('pcname',)

在Django的ORM中通过设置Field属性直接定义隐藏字段:editable = False

例如

class PostCodes(models.Model):
  gisid  = models.IntegerField(primary_key=True)
  pcname = models.CharField(max_length=32, db_index=True, editable=False)
  ...

但是,直接设置或更改模型的字段可能并不总是可行或有利的。原则上,以下admin.py 设置可以工作,但由于exclude 是一个 InlineModelAdmin 选项,所以不会。

class PostCodesAdmin(admin.ModelAdmin):
     exclude = ('pcname',)
....

至少在 Django 1.4(以及可能的更高版本号)中有效的解决方案是:

class PostCodesAdmin(admin.ModelAdmin):
  def get_form(self, request, obj=None, **kwargs):
      form = super(PostCodesAdmin, self).get_form(request, obj, **kwargs)
      del form.base_fields['enable_comments'] 
      return form

对于项目的管理列表视图,只需省略不需要的字段即可: 例如

class PostCodesAdmin(admin.ModelAdmin):
  list_display = ('id', 'gisid', 'title', )

【讨论】:

在 Django 1.8 exclude = ('fieldname',) 确实适用于 admin.ModelAdmin,因此不必再从 InlineModelAdmin 继承。 也适用于 Django 1.6.11。它实际上已经存在for quite a while(从 v1.0 开始)。它没有回答这里提出的问题,但它解决了我的问题:)【参考方案3】:

中肯的@Lorenz @mrts 回答

在 Django 2.1 中,我发现如果字段已经通过 fields = 指定,则 exclude 不起作用。

在这种情况下,您可以使用

self.fields.remove('title')

必须将字段定义为列表 [] 才能正常工作

【讨论】:

你在哪里添加这个? 这将在 admin.py 中。在扩展 admin.ModelAdmin 的类中,您将需要一个 get_form 函数。 def get_form(self, request, obj=None, **kwargs):self.fields.remove()可以在那里调用 谢谢。我认为澄清对阅读本文的其他人有用。【参考方案4】:

我试图覆盖get_form() 函数,但是当我切换不同的记录时会出现一些混淆错误。我发现有一个 get_exclude() 函数我们可以覆盖。

用途:

class BookAdmin(admin.ModelAdmin):
    def get_exclude(self, request, obj=None):
        if obj and obj.type == "1":
            # When you create new data the obj is None
            return ("title", )
        return super().get_exclude(request, obj)

【讨论】:

【参考方案5】:

如果要保持表单中的值(例如根据请求设置值,即用户)并隐藏字段,可以将小部件更改为forms.HiddenInput()

from django import forms

...

    def get_form(self, request, obj=None, **kwargs):
        """Set defaults based on request user"""
        # update user field with logged user as default
        form = super().get_form(request, obj, **kwargs)
        form.base_fields["user"].initial = request.user.id
        form.base_fields["user"].widget = forms.HiddenInput()
        return form

【讨论】:

以上是关于如何隐藏 django-admin 中的某些字段?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止在 WooCommerce 中的某些国家/地区隐藏邮政编码/邮政编码字段

如何隐藏/排除graphene_django中请求实体的某些外键字段?

最小化 django-admin 中的列表过滤器

Django-admin按多个字段排序

如何使用 ajax 在 Django-admin 表格内联中读取/写入输入字段?

如何在 Django-admin 中添加自定义搜索框?