Python 如何从带有外键的模型角度在Django admin中显示相关对象?
我用外键连接了两个Django模型:Python 如何从带有外键的模型角度在Django admin中显示相关对象?,python,django,django-admin,Python,Django,Django Admin,我用外键连接了两个Django模型: class Author(models.Model): ... class Book(models.Model): author = models.ForeignKey(Author) 请考虑下面的管理示例(我想做相反的事情): 通过这个例子,我们可以在管理员界面中看到所有作者,以及每个作者的书籍 现在,我想用另一种方式来解释它。在管理中为每本书设置en条目,并在书的详细信息上显示作者信息(可只读)。我尝试了下面的解决方案,但显然不起作用
class Author(models.Model):
...
class Book(models.Model):
author = models.ForeignKey(Author)
请考虑下面的管理示例(我想做相反的事情):
通过这个例子,我们可以在管理员界面中看到所有作者,以及每个作者的书籍 现在,我想用另一种方式来解释它。在管理中为每本书设置en条目,并在书的详细信息上显示作者信息(可只读)。我尝试了下面的解决方案,但显然不起作用:from django.contrib import admin
from my_app.models import Author, Book
class AuthorInline(admin.TabularInline):
model = Author
class BookAdmin(admin.ModelAdmin):
inlines = [
AuthorInline,
]
admin.site.register(Book, BookAdmin)
Django引发了一个错误:
:(admin.E202)“我的应用程序作者”没有“我的应用程序书”的外键。
你知道怎么做吗
更多背景:
- Django 1.11
- 我想将书和作者显示为完全只读,因此书的外键不会更改(至少不会从管理员处更改)
- 正如错误所说:
class 'my_app.admin.AuthorInline'>: (admin.E202) 'my_app.Author' has no ForeignKey to 'my_app.Book'.
您需要在作者表中添加外键,该参考书籍表
第一个是有效的,因为书中有一个引用作者的外键。你不能这样做。内线仅在一个方向上有意义
这样做的方法是定义author字段的显示,以便它自动为您提供足够的信息;例如,通过定义
\uu str\uu
方法。在这里,我的解决方案可能不是最好的,但它很有效!:)
这个想法是改变模板,从而能够以我想要的方式显示它
admin.py:
class BookAdmin(admin.ModelAdmin):
...
change_form_template = 'admin/book_details.html'
def change_view(self, request, object_id, form_url='', extra_context=None):
extra_context = extra_context or {}
extra_context['book'] = Book.objects.get(id=object_id)
extra_context['author'] = extra_context['book'].author
return super().change_view(request, object_id, form_url, extra_context=extra_context)
admin.site.register(Book, BookAdmin)
对于模板,我只是复制/通过
管理员/book_details.html:
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
{% block coltype %}colM{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
› {% if has_change_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
› {% if add %}{% blocktrans with name=opts.verbose_name %}Add {{ name }}{% endblocktrans %}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% block content %}
# Display here want you want !
{% endblock %}
{%extends“admin/base\u site.html”%}
{%load i18n admin\u URL静态admin\u modify%}
{%block extrastyle%}{{block.super}{%endblock%}
{%block coltype%}colM{%endblock%}
{%block breadcrumbs%}
&rsaquo;
&rsaquo;{%if拥有{u change_permission%}{%else%}{{opts.verbose_name_复数{124; capfirst}}{%endif%}
&rsaquo;{%if add%}{%blocktrans with name=opts.verbose_name%}add{{name}{%endblocktrans%}{%else%}{{{original | truncatewords:“18”}{%endif%}
{%endblock%}
{%block content%}
#在这里展示你想要的!
{%endblock%}
我查看了Django admin的模板,以便能够以与默认模板相同的方式显示我的书和作者。所以我的用户不会被这个视图打断
如果你找到更好的方法,请告诉我!:) 有
ModelAdmin.readonly\u字段
可以在ModelAdmin本身或模型上调用,并在添加/更改表单上显示它们。()
如果您想在管理员的图书更改表上显示作者姓名,您可以这样做:
class BookAdmin(admin.ModelAdmin):
只读_字段=['get_author_name']
[...]
def get_作者姓名(自我、书籍):
返回book.author.name
所有只读字段将显示在窗体的常规字段下。
您还可以通过修改ModelForm.get\u fields()
自定义字段的显示方式
如果您这样做,您就省去了覆盖模板的麻烦。为了给您一个提示,我认为您需要指定关系的backref属性,这样继承就可以双向识别。恐怕我不确定语法,尤其是Django 1.11,但希望这能给你一个线索。是的,我使用了“related_name”属性,这样它可以从关系的两侧使用:)是的,但在作者模型上使用FK没有意义,作者可以出版几本书。我认为最好在两者之间的关系中添加一个backref,以便您可以从各自的模型中访问每一本书。您始终可以添加一个类似于模型的关联对象。我想知道在这种情况下是否有内联以外的内容,但似乎没有:(事实上,我有太多关于我作者模型的信息,不能只显示str解决方案,甚至可以通过可调用项来显示。好吧,这是可以做到的。但不是那么容易。这是它的主要部分。希望完成。我从我正在做的一个项目中计算出来。是的,没有文档,但至少向您展示了获取外键作为内联键所要经历的困难。)表单(当然,您可以将其设置为只读)。
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}" />{% endblock %}
{% block coltype %}colM{% endblock %}
{% block breadcrumbs %}
<div class="breadcrumbs">
<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
› {% if has_change_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
› {% if add %}{% blocktrans with name=opts.verbose_name %}Add {{ name }}{% endblocktrans %}{% else %}{{ original|truncatewords:"18" }}{% endif %}
</div>
{% endblock %}
{% block content %}
# Display here want you want !
{% endblock %}