Bor*_*jaX 9 python django admin relationship inline-formset
我有一个三级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 | |
| |____________________________| |
| |
|___________________________________|
Run Code Online (Sandbox Code Playgroud)
模型看起来或多或少(它们已经针对这个问题进行了简化),例如:
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(...)
Run Code Online (Sandbox Code Playgroud)
现在,我知道在Django Admin中嵌套两个级别的关系是非常复杂的,我并不是试图嵌入到嵌套中InvoiceItem并将其SubInvoice嵌套到Invoice.这很好,但由于嵌套内联的困难,我准备放弃它.编号:我希望做的是显示了什么Invoice,并作为inline其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 | |
| |____________________________| |
| |
|___________________________________|
Run Code Online (Sandbox Code Playgroud)
(InvoiceItems作为Invoice(s)的内联而未显示其中的任何信息SubInvoices)
我在以下方面尝试了以下内容admin.py:
class InvoiceItemInline(admin.StackedInline):
fk_name = 'sub_invoice__invoice'
model = InvoiceItem
class InvoiceAdmin(admin.ModelAdmin):
inlines = (InvoiceItemInline,)
Run Code Online (Sandbox Code Playgroud)
但这给了我一个错误:
<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,)
Run Code Online (Sandbox Code Playgroud)
但那时(我期待的这个)产生了这个错误:
<class 'server.admin.invoices.InvoiceItemInline'>: (admin.E202) 'server.InvoiceItem' has no ForeignKey to 'server.Invoice'.
有没有办法实现这个目标?先感谢您.
PS:
截至目前,我有一个"修补"的解决方案似乎是规范的方式:
Invoice模型.admin.ModelAdmin SubInvoiceInvoiceSubInvoice在admin中注册,这样我们就可以计算出其管理视图的链接.InvoiceItems上述SubInvoice的观点.SubInvoice(s)的管理视图的链接Invoice几乎在其他SO答案中描述了什么.
但这种方法的问题在于它不会让我一眼就看到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 |
| |____________________________| | |________________________|
| |
|___________________________________|
Run Code Online (Sandbox Code Playgroud)
我认为你的问题可以使用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)
Run Code Online (Sandbox Code Playgroud)
我建议您在您的课程中使用该课程,并在您的课程中views.py使用它。在前端也使用库,因为这看起来非常整洁。inlineformset_factoryforms.pyjquery-formset
注意:您还可以在外键on_delete=models.CASCADE上使用 if InvoiceItem,因此如果删除其中一项,则 InvoiceItem 也将被删除,或者models.SET_NULL,无论您喜欢哪个。
希望这可以帮助你。
| 归档时间: |
|
| 查看次数: |
1325 次 |
| 最近记录: |