格式化 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_horizo​​ntal,它使用了不同小部件的单个实例,其中您有一个所有产品列表和另一个相关产品列表,您可以在后来从前者。这解决了缓慢,但它仍然没有显示相关的 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 中呈现的内联多对多相关模型的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django admin 中自定义多对多内联模型

用于递归多对多的 Django Admin 内联

使用 django admin 进行一对多内联选择

Django内联表单集通过另一个模型在多对多关系中过滤

Django Admin Cookbook-23如何在Django admin中添加嵌套的内联

多对多字段的 Django 1.2.1 内联管理