在wagtail admin中编辑django'through'模型内联?

时间:2018-06-18 20:35:21

标签: django wagtail

[使用更好的代码示例编辑]

根据标题,我试图在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.或者我只是没有内联面板,而是选择。

我假设是这种情况,因为创建和添加方法不能通过模型​​工作,是这样吗?

如果是这样,你可以建议我改写应用程序的方式,以便允许我在管理员和我的代码中创建包含产品的订单吗?

1 个答案:

答案 0 :(得分:1)

InlinePanel仅适用于一对多ParentalKey关系,不适用于ManyToManyField。这应该不成问题,因为ParentalKey非常适合这种情况:

  • 具有ManyToManyField模型的through实际上只是两个背对背的一对多关系;
  • ParentalKey是为与父模型紧密联系的关系而设计的,因为它们总是被编辑,验证和保存为单个单元。对于ProductInOrderCountOrder之间的关系(ProductInOrderCount记录在概念上是Order的一部分)而言,这是正确的,但ProductInOrderCount和{ {1}}(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')字段可以省略。