在 wagtail 管理中编辑 django 'through' 模型内联?
Edit django 'through' model inline in wagtail admin?
[编辑了更好的代码示例]
根据标题,我正在尝试允许在 Wagtail 中对一个非常简单的商店页面进行内联编辑(可能会将其放入一个简单的包中):
有以下型号:
class Product(ClusterableModel):
page = ParentalKey(MiniShopPage, on_delete=models.CASCADE, related_name='shop_products')
name = models.CharField(max_length=255)
description = models.CharField(max_length=2500)
downloadable = models.BooleanField()
price = models.FloatField()
image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
# define the content_panels
panels = [
FieldPanel('name'),
FieldPanel('description'),
FieldPanel('downloadable'),
FieldPanel('price'),
ImageChooserPanel('image'),
]
class Order(TimeStampedModel, ClusterableModel):
'''
Example of use outside of the admin:
p = Product.objects.first()
order = Order.objects.create(client_email='someone@hotmail.com', gift_amount=0)
quantities = ProductInOrderCount(product=p, order=order, quantity=2)
quantities.save()
for itm in order.productinordercount_set.all():
print(itm.quantity)
'''
is_fulfilled = models.BooleanField(default=False)
is_paid_for = models.BooleanField(default=False)
client_email = models.EmailField(blank=False)
gift_amount = models.PositiveIntegerField()
# products = M2MTHROUGH
# the through model stores the quantity
products = models.ManyToManyField(Product, through='ProductInOrderCount')
content_panels = [
FieldPanel('is_fulfilled'),
FieldPanel('is_paid_for'),
FieldPanel('client_email'),
FieldPanel('gift_amount'),
InlinePanel('products'),
]
class OrderModelAdmin(ModelAdmin):
model = Order
menu_label = 'Orders'
...
modeladmin_register(OrderModelAdmin)
class ProductInOrderCount(Orderable):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
order = models.ForeignKey(Order, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
棘手的事情是我收到错误 Cannot set values on a ManyToManyField which specifies an intermediary model.
或者我根本没有得到内联面板,而是 select。
我假设是这种情况,因为创建和添加方法不能通过模型工作,是这样吗?
如果可以,您能否建议我重写应用程序的方法,以便允许我在管理员和我的代码中创建包含产品的订单?
InlinePanel
仅适用于一对多 ParentalKey
关系,不适用于 ManyToManyField
。这应该不是问题,因为 ParentalKey
非常适合这种情况:
- 带有
through
模型的ManyToManyField
实际上只是两个背对背的一对多关系;
ParentalKey
专为与父模型密切相关的关系而设计,因为它们始终作为一个单元进行编辑、验证和保存。 ProductInOrderCount
和 Order
之间的关系是这样(ProductInOrderCount
记录在概念上是 Order
的一部分),但 ProductInOrderCount
和 Product
(ProductInOrderCount
不是 Product
的一部分)。
这将为您提供如下模型定义:
class ProductInOrderCount(Orderable):
order = ParentalKey(Order, on_delete=models.CASCADE, related_name='ordered_products')
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
您的 Order
模型可以有一个 InlinePanel('ordered_products')
,并且可以省略 products
字段。
[编辑了更好的代码示例]
根据标题,我正在尝试允许在 Wagtail 中对一个非常简单的商店页面进行内联编辑(可能会将其放入一个简单的包中):
有以下型号:
class Product(ClusterableModel):
page = ParentalKey(MiniShopPage, on_delete=models.CASCADE, related_name='shop_products')
name = models.CharField(max_length=255)
description = models.CharField(max_length=2500)
downloadable = models.BooleanField()
price = models.FloatField()
image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
# define the content_panels
panels = [
FieldPanel('name'),
FieldPanel('description'),
FieldPanel('downloadable'),
FieldPanel('price'),
ImageChooserPanel('image'),
]
class Order(TimeStampedModel, ClusterableModel):
'''
Example of use outside of the admin:
p = Product.objects.first()
order = Order.objects.create(client_email='someone@hotmail.com', gift_amount=0)
quantities = ProductInOrderCount(product=p, order=order, quantity=2)
quantities.save()
for itm in order.productinordercount_set.all():
print(itm.quantity)
'''
is_fulfilled = models.BooleanField(default=False)
is_paid_for = models.BooleanField(default=False)
client_email = models.EmailField(blank=False)
gift_amount = models.PositiveIntegerField()
# products = M2MTHROUGH
# the through model stores the quantity
products = models.ManyToManyField(Product, through='ProductInOrderCount')
content_panels = [
FieldPanel('is_fulfilled'),
FieldPanel('is_paid_for'),
FieldPanel('client_email'),
FieldPanel('gift_amount'),
InlinePanel('products'),
]
class OrderModelAdmin(ModelAdmin):
model = Order
menu_label = 'Orders'
...
modeladmin_register(OrderModelAdmin)
class ProductInOrderCount(Orderable):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
order = models.ForeignKey(Order, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
棘手的事情是我收到错误 Cannot set values on a ManyToManyField which specifies an intermediary model.
或者我根本没有得到内联面板,而是 select。
我假设是这种情况,因为创建和添加方法不能通过模型工作,是这样吗?
如果可以,您能否建议我重写应用程序的方法,以便允许我在管理员和我的代码中创建包含产品的订单?
InlinePanel
仅适用于一对多 ParentalKey
关系,不适用于 ManyToManyField
。这应该不是问题,因为 ParentalKey
非常适合这种情况:
- 带有
through
模型的ManyToManyField
实际上只是两个背对背的一对多关系; ParentalKey
专为与父模型密切相关的关系而设计,因为它们始终作为一个单元进行编辑、验证和保存。ProductInOrderCount
和Order
之间的关系是这样(ProductInOrderCount
记录在概念上是Order
的一部分),但ProductInOrderCount
和Product
(ProductInOrderCount
不是Product
的一部分)。
这将为您提供如下模型定义:
class ProductInOrderCount(Orderable):
order = ParentalKey(Order, on_delete=models.CASCADE, related_name='ordered_products')
product = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
您的 Order
模型可以有一个 InlinePanel('ordered_products')
,并且可以省略 products
字段。