格式化 django admin 中呈现的内联多对多相关模型
Posted
技术标签:
【中文标题】格式化 django admin 中呈现的内联多对多相关模型【英文标题】:Formatting inline many-to-many related models presented in django admin 【发布时间】:2011-02-23 21:41:39 【问题描述】:我有两个 django 模型(简化版):
class Product(models.Model):
name = models.TextField()
price = models.IntegerField()
class Invoice(models.Model):
company = models.TextField()
customer = models.TextField()
products = models.ManyToManyField(Product)
我希望在管理员的发票页面中将相关产品作为一个漂亮的表格(产品字段),并能够链接到各个相应的产品页面。
我的第一个想法是使用管理员的内联 - 但 django 为每个相关产品使用了一个选择框小部件。这没有链接到产品页面,而且由于我有数千种产品,并且每个选择框独立下载所有产品名称,它很快就会变得异常缓慢。
所以我转而按照 here 的建议使用 ModelAdmin.filter_horizontal,它使用了不同小部件的单个实例,其中您有一个所有产品列表和另一个相关产品列表,您可以在后来从前者。这解决了缓慢,但它仍然没有显示相关的 Product 字段,并且它不可链接。
那么,我该怎么办?调整观点?覆盖模型窗体?我用 Google 搜索了一下,找不到任何此类代码的示例...
【问题讨论】:
【参考方案1】:也许这不是您所期望的,但我会介绍 InvoiceItem 模型,它将 Invoice 链接到 Product。所以你会有 2x 1:n 而不是 m:n 关系。然后使用 InvoiceItem 的内联自定义表单和该表单中的 raw_id_fields 用于产品选择。
在 InvoiceItem 表单中,您可以添加只读字段来显示您需要显示的值。您必须在表单的 init 中为这些字段提供数据,从 InvoiceItem 实例中读取它们。或者您也可以从 raw_id_field 小部件派生,并在此小部件的渲染方法中附加一些来自产品模型的额外数据?
【讨论】:
【参考方案2】:这是一个老问题,但我今天已经涉及到它。
您可以在这里找到答案 - https://blog.ionelmc.ro/2012/01/19/tweaks-for-making-django-admin-faster/
代码:
class MyAdmin(admin.TabularInline):
fields = 'myfield',
def formfield_for_dbfield(self, db_field, **kwargs):
formfield = super(MyAdmin, self).formfield_for_dbfield(db_field, **kwargs)
if db_field.name == 'myfield':
# dirty trick so queryset is evaluated and cached in .choices
formfield.choices = formfield.choices
return formfield
这可以将您的等待时间从大约 5 分钟缩短到大约 15 秒。
【讨论】:
以上是关于格式化 django admin 中呈现的内联多对多相关模型的主要内容,如果未能解决你的问题,请参考以下文章