Django admin:内联直接到二级关系

2023-12-26

我有一个三级Invoice我想在 Django 的管理区域中显示的模型......以“某种形式”special" way.

请允许我提供一些背景信息:

Each Invoice是由几个符合SubInvoice(s),以及每个SubInvoice是由几个符合InvoiceItem(s),其中包含Products由客户购买。

按逻辑来说,它会是这样的(希望ascii艺术作品)

+---------- Invoice id=3 -----------+
|       Full total: $100.00         |
|                                   |
|  +----- Sub Invoice id=1 -----+   |
|  |      Subtotal $70          |   |
|  |                            |   |
|  |    Item 1 in SubInv.1      |   |
|  |    Item 2 in SubInv.1      |   |
|  |    Item 3 in SubInv.1      |   |
|  |____________________________|   |
|                                   |
|  +----- Sub Invoice id=2 -----+   |
|  |      Subtotal $30          |   |
|  |                            |   |
|  |    Item 1 in SubInv.2      |   |
|  |    Item 2 in SubInv.2      |   |
|  |____________________________|   |
|                                   |
|___________________________________|

这些模型看起来或多或少(它们已经针对这个问题进行了简化)如下:

class Invoice(models.Model):
    full_total = DecimalField(...)
    # has a .sub_invoices RelatedManager through a backref from SubInvoice

class SubInvoice(models.Model):
    sub_total = DecimalField(...)
    invoice = ForeignKey('server.Invoice', related_name='sub_invoices')
    # has an .items RelatedManager through a backref from InvoiceItem

class InvoiceItem(models.Model):
    sub_invoice = ForeignKey('server.SubInvoice', related_name='items')
    product = ForeignKey('server.Product', related_name='+')
    quantity = PositiveIntegerField(...)
    price = DecimalField(...)

现在,我知道在 Django Admin 中嵌套两层关系非常复杂,而且我并不想嵌套InvoiceItem进入SubInvoice并将其嵌套到Invoice。那太好了,但由于嵌套内联的困难,我准备放弃它。No:我想做的是展示Invoice并且,作为inline, its Items, “跳跃”通过Invoice.sub_invoices__items。我不太关心显示的信息SubInvoice(s),但我确实关心其中的信息Invoice并在InvoiceItems.

我的意思是,基本上,我想要(或“我可以一起生活”,相反)如果Invoice管理视图如下所示:

+---------- Invoice id=3 -----------+
|       Full total: $100.00         |
|                                   |
|  +----------------------------+   |
|  |                            |   |
|  |    Item 1 in SubInv.1      |   |
|  |    Item 2 in SubInv.1      |   |
|  |    Item 3 in SubInv.1      |   |
|  |    Item 1 in SubInv.2      |   |
|  |    Item 2 in SubInv.2      |   |
|  |____________________________|   |
|                                   |
|___________________________________|

(InvoiceItems作为内联Invoice(s) 未显示任何有关该的信息SubInvoices in it)

我已经尝试过以下操作admin.py:

class InvoiceItemInline(admin.StackedInline):
    fk_name = 'sub_invoice__invoice'
    model = InvoiceItem

class InvoiceAdmin(admin.ModelAdmin):
    inlines = (InvoiceItemInline,)

但这给了我一个错误:

<class 'server.admin.invoices.InvoiceItemInline'>: (admin.E202) 'server.InvoiceItem' has no field named 'sub_invoice__invoice'.

我也直接尝试过这个:

class InvoiceItemInline(admin.StackedInline):
    model = InvoiceItem

class InvoiceAdmin(admin.ModelAdmin):
    inlines = (InvoiceItemInline,)

但随后(我期待的这个)产生了这个错误:

<class 'server.admin.invoices.InvoiceItemInline'>: (admin.E202) 'server.InvoiceItem' has no ForeignKey to 'server.Invoice'.

有什么办法可以实现这一点吗?先感谢您。

PS:

截至目前,我有一个“修补”解决方案,这似乎是规范的方式:

  • 注册Invoice model.
  • 注册一个admin.ModelAdmin https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#modeladmin-objects inline为了SubInvoice(这个内联将被“内联”到Invoice的模型管理员)。
  • 还要注册SubInvoice在管理中,因此我们可以计算到其管理视图的链接。
  • Add an inline的看法InvoiceItems对于前述的SubInvoice's view.
  • 添加指向管理视图的链接SubInvoice(s) 在Invoice

与其他内容中描述的内容差不多所以。回答 https://stackoverflow.com/a/14328715/289011.

但这种方法的问题是它不会让我看到Invoice和它的InvoiceItems一目了然(我看到发票,其中包含 sub_invoices,然后在 sub_invoices 内联中,有一个指向 InvoiceItems 的链接,我必须单击该链接才能查看项目)。如果我能够摆脱对该链接的需要,那就太好了。

这就是我现在所拥有的,基本上:

+---------- Invoice id=3 -----------+
|       Full total: $100.00         |
|                                   |
|  +----- Sub Invoice id=1 -----+   |       +--- Sub Invoice id=1 ---+
|  |      Subtotal $70          |   |       |   Item 1 in SubInv.1   |
|  |                            |   |       |   Item 2 in SubInv.1   |
|  |    <a>Click for items ==============>  |   Item 3 in SubInv.1   |
|  |____________________________|   |       |________________________|
|                                   |
|  +----- Sub Invoice id=2 -----+   |
|  |      Subtotal $30          |   |       +--- Sub Invoice id=2 ---+
|  |                            |   |       |   Item 1 in SubInv.2   |
|  |    <a>Click for items ==============>  |   Item 2 in SubInv.2   |
|  |____________________________|   |       |________________________|
|                                   |
|___________________________________|

我认为你的问题可以通过使用来解决ManyToManyField + through。 (这是一个例子)

#models.py
class Invoice(models.Model):
    full_total = DecimalField(...)
    # has a .sub_invoices RelatedManager through a backref from SubInvoice

class SubInvoice(models.Model):
    sub_total = DecimalField(...)
    invoice = ManyToManyField(
        'server.Invoice',
        through='server.InvoiceItem',
        through_fields=('sub_invoice', 'invoice'))
    # has an .items RelatedManager through a backref from InvoiceItem

class InvoiceItem(models.Model):
    sub_invoice = ForeignKey('server.SubInvoice')
    invoice = ForeignKey('server.Invoice')
    product = ForeignKey('server.Product', related_name='+')
    quantity = PositiveIntegerField(...)
    price = DecimalField(...)

#admin.py
from django.contrib import admin
from .models import InvoiceItem, Invoice, SubInvoice


class InvoiceItemInline(admin.TabularInline):
    model = InvoiceItem
    extra = 1


class InvoiceAdmin(admin.ModelAdmin):
    inlines = (InvoiceItemInline,)


admin.site.register(Invoice, InvoiceAdmin)
admin.site.register(SubInvoice, InvoiceAdmin)

我建议您在您的课程中开设这一课程views.py并使用inlineformset_factory在你的forms.py为了这。 使用jquery-formset前端也有库,因为这看起来非常整洁。

笔记: 您还可以使用on_delete=models.CASCADE如果你想在InvoiceItem在外键上,因此如果删除其中一项,则 InvoiceItem 也将被删除,或者models.SET_NULL,无论您喜欢哪个。

希望这可以帮助你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django admin:内联直接到二级关系 的相关文章

随机推荐