可以“list_display” 在 Django ModelAdmin 中显示外键字段的属性?
我有一个与 Book
具有外键关系的 Person
模型,该模型有许多字段,但我最关心的是 author
(一个标准的 CharField)。
话虽这么说,在我的 PersonAdmin
模型中,我想使用 list_display
显示 book.author
:
class PersonAdmin(admin.ModelAdmin):
list_display = ['book.author',]
我已经尝试了所有这样做的方法显而易见,但似乎没有任何效果。
有什么建议么?
I have a Person
model that has a foreign key relationship to Book
, which has a number of fields, but I'm most concerned about author
(a standard CharField).
With that being said, in my PersonAdmin
model, I'd like to display book.author
using list_display
:
class PersonAdmin(admin.ModelAdmin):
list_display = ['book.author',]
I've tried all of the obvious methods for doing so, but nothing seems to work.
Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
作为另一种选择,您可以进行如下查找:
对于 Django 3.2 或更高版本,请参阅此答案
As another option, you can do lookups like:
For Django 3.2 or higher, please refer to this answer
尽管上面有很多很好的答案,并且由于我是 Django 新手,但我仍然被困住了。 这是我从一个非常新手的角度的解释。
models.py
admin.py(不正确的方式) - 您认为使用“model__field”来引用会起作用,但它不会
admin.py(正确的方式) - 这是您以 Django 方式引用外键名称的方式。
有关其他参考,请参阅 Django 模型链接 此处
Despite all the great answers above and due to me being new to Django, I was still stuck. Here's my explanation from a very newbie perspective.
models.py
admin.py (Incorrect Way) - you think it would work by using 'model__field' to reference, but it doesn't
admin.py (Correct Way) - this is how you reference a foreign key name the Django way
For additional reference, see the Django model link here
请注意,添加
get_author
函数会减慢管理中的 list_display 速度,因为显示每个人都会进行 SQL 查询。为了避免这种情况,您需要修改PersonAdmin中的
get_queryset
方法,例如:Please note that adding the
get_author
function would slow the list_display in the admin, because showing each person would make a SQL query.To avoid this, you need to modify
get_queryset
method in PersonAdmin, for example:和其他人一样,我也选择了可调用的。 但它们有一个缺点:默认情况下,您无法订购它们。 幸运的是,有一个解决方案:
Django >= 1.8
Django < 1.8
Like the rest, I went with callables too. But they have one downside: by default, you can't order on them. Fortunately, there is a solution for that:
Django >= 1.8
Django < 1.8
对于 Django >= 3.2
使用 Django 3.2 或更高版本执行此操作的正确方法是使用 显示装饰器
For Django >= 3.2
The proper way to do it with Django 3.2 or higher is by using the display decorator
根据文档,您只能显示外键的
__unicode__
表示形式:http://docs.djangoproject.com/en/dev/ref/contrib/admin/#list-display
看起来很奇怪,它不支持
' book__author'
样式格式在 DB API 中的其他任何地方都使用。结果是此功能的票证,被标记为“无法修复”。
According to the documentation, you can only display the
__unicode__
representation of a ForeignKey:http://docs.djangoproject.com/en/dev/ref/contrib/admin/#list-display
Seems odd that it doesn't support the
'book__author'
style format which is used everywhere else in the DB API.Turns out there's a ticket for this feature, which is marked as Won't Fix.
我刚刚发布了一个片段,使 admin.ModelAdmin 支持 '__' 语法:
http://djangosnippets.org/snippets/ 2887章
第
2887每行的数据库命中。
I just posted a snippet that makes admin.ModelAdmin support '__' syntax:
http://djangosnippets.org/snippets/2887/
So you can do:
This is basically just doing the same thing described in the other answers, but it automatically takes care of (1) setting admin_order_field (2) setting short_description and (3) modifying the queryset to avoid a database hit for each row.
PyPI 中有一个非常易于使用的包可以完全处理这个问题: 。 您还可以查看 GitHub 中的代码。
使用此功能,您想要实现的目标非常简单:
两个链接都包含安装和使用的完整详细信息,因此我不会将它们粘贴到此处,以防它们发生更改。
顺便说一句,如果您已经使用了
model.Admin
以外的其他内容(例如我使用的是SimpleHistoryAdmin
),您可以执行以下操作:class MyAdmin(SimpleHistoryAdmin,RelatedFieldAdmin)
。There is a very easy to use package available in PyPI that handles exactly that: django-related-admin. You can also see the code in GitHub.
Using this, what you want to achieve is as simple as:
Both links contain full details of installation and usage so I won't paste them here in case they change.
Just as a side note, if you're already using something other than
model.Admin
(e.g. I was usingSimpleHistoryAdmin
instead), you can do this:class MyAdmin(SimpleHistoryAdmin, RelatedFieldAdmin)
.您可以使用可调用函数在列表显示中显示您想要的任何内容。 它看起来像这样:
You can show whatever you want in list display by using a callable. It would look like this:
如果您有很多关系属性字段要在
list_display
中使用,并且不想为每个字段创建一个函数(及其属性),那么一个肮脏但简单的解决方案将覆盖ModelAdmin< /code> instace
__getattr__
方法,动态创建可调用对象:如要点< /a>
可调用的特殊属性,例如
boolean
和short_description
必须定义为ModelAdmin
属性,例如book__author_verbose_name = 'Author name'和
category__is_new_boolean = True
。可调用的
admin_order_field
属性是自动定义的。不要忘记使用 ModelAdmin 中的“list_select_lated”>list_select_lated 属性使 Django 避免额外的查询。
If you have a lot of relation attribute fields to use in
list_display
and do not want create a function (and it's attributes) for each one, a dirt but simple solution would be override theModelAdmin
instace__getattr__
method, creating the callables on the fly:As gist here
Callable especial attributes like
boolean
andshort_description
must be defined asModelAdmin
attributes, egbook__author_verbose_name = 'Author name'
andcategory__is_new_boolean = True
.The callable
admin_order_field
attribute is defined automatically.Don't forget to use the list_select_related attribute in your
ModelAdmin
to make Django avoid aditional queries.这个已经被接受了,但是如果还有其他傻瓜(像我一样)没有立即从 目前接受的答案中得到它,这里有更多细节。
ForeignKey
引用的模型类需要在其中有一个__unicode__
方法,如下所示:这对我来说很重要,并且应该适用于上述场景。 这适用于 Django 1.0.2。
This one's already accepted, but if there are any other dummies out there (like me) that didn't immediately get it from the presently accepted answer, here's a bit more detail.
The model class referenced by the
ForeignKey
needs to have a__unicode__
method within it, like here:That made the difference for me, and should apply to the above scenario. This works on Django 1.0.2.
我可能会迟到,但这是另一种方法。 您可以简单地在模型中定义一个方法并通过
list_display
访问它,如下所示:models.py
admin.py
但是这个和另一个上面提到的方法在列表视图页面的每行添加两个额外的查询。 为了优化这一点,我们可以重写
get_queryset
来注释必填字段,然后在 ModelAdmin 方法admin.py中使用带注释的字段
I may be late, but this is another way to do it. You can simply define a method in your model and access it via the
list_display
as below:models.py
admin.py
But this and the other approaches mentioned above add two extra queries per row in your listview page. To optimize this, we can override the
get_queryset
to annotate the required field, then use the annotated field in our ModelAdmin methodadmin.py
如果您在内联中尝试,您将不会成功,除非:
在您的内联中:
在您的模型(MyModel)中:
if you try it in Inline, you wont succeed unless:
in your inline:
in your model (MyModel):
AlexRobbins 的答案对我有用,除了前两行需要位于模型中(也许这是假设的?),并且应该引用 self:
然后管理部分就可以很好地工作。
AlexRobbins' answer worked for me, except that the first two lines need to be in the model (perhaps this was assumed?), and should reference self:
Then the admin part works nicely.
我更喜欢这个:
I prefer this: