如何隐藏 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中请求实体的某些外键字段?