gpt4 book ai didi

python - Django 管理员 : Inline straight to second-level relationship

转载 作者:太空狗 更新时间:2023-10-29 21:09:25 25 4
gpt4 key购买 nike

我有一个三级Invoice我想在 Django 的管理区域中显示的模型...以一种“特殊”的方式。

请允许我提供一些背景知识:

每个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 中.那太好了,但由于嵌套内联的困难,我准备放弃它。 否:我想做的是显示 Invoice并且,作为 inline , 它的 Items , “跳跃” 通过 Invoice.sub_invoices__items .我不太关心 SubInvoice 中显示的信息(s),但我确实关心 Invoice 中的信息在InvoiceItems .

我的意思是,基本上,如果 Invoice,我希望(或者说“我可以忍受”)管理 View 如下所示:

+---------- 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 的任何信息)

我在 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'.

有什么办法可以实现吗?提前谢谢你。

附言:

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

  • 注册 Invoice模型。
  • 注册 admin.ModelAdmin 内联 SubInvoice (此内联将“内联”到 Invoice 的 ModelAdmin 中)。
  • 同时注册 SubInvoice在管理员中,因此我们可以计算到其管理员 View 的链接。
  • 添加 InvoiceItems内联 View 上述SubInvoice的观点。
  • 添加指向 SubInvoice 的管理 View 的链接(s) 在 Invoice

其他 S.O. answer 中描述的内容差不多.

但这种方法的问题是它不会让我看到 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 中为此使用类,并为此在您的 forms.py 中使用 inlineformset_factory。在您的前端中也使用 jquery-formset 库,因为这看起来非常整洁。

注意:如果你想在外键上的 InvoiceItem 中,你也可以使用 on_delete=models.CASCADE,所以如果其中一个项目被删除,那么 InvoiceItem 也将被删除,或 models.SET_NULL,以您喜欢的为准。

希望这对您有所帮助。

关于python - Django 管理员 : Inline straight to second-level relationship,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44477257/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com