Django admin:基于其他内联更新内联

时间:2013-02-18 20:46:47

标签: django django-forms django-admin

您好,

在管理员面板中,我创建了添加产品的表单。表单包括2个内联表单集,因为有一些与产品相关的模型。用户可以创建产品,然后定义该产品的不同属性的变体。我将举例说明这一点。用户有一个3种不同颜色的T恤,并希望以不同的价格添加它们。 T恤是作为具有3种变化的产品而创建的。

class Detail(models.Model):
    product = models.ForeignKey('Product')
    attribute = models.ForeignKey('Attribute')
    value = models.CharField(max_length=500)

class Attribute(models.Model):
    name = models.CharField(max_length=300)

class Variant(models.Model):
    product = models.ForeignKey(Product)
    details = models.ManyToManyField(Detail)
    quantity = models.IntegerField()
    price = models.DecimalField(max_digits=6, decimal_places=2)

我省略了产品,因为它无关紧要。

class DetailInline(admin.TabularInline):
    model = Detail

class VariantInline(admin.StackedInline):
    model = Variant

class ProductAdmin(admin.ModelAdmin):
    class Meta:
        model = Product

    inlines = [DetailInline, VariantInline]

这很好用,模型保存得很好,我确实有Variants内联的问题。变量内联显示详细信息对象,但仅显示已保存在数据库中的对象。为了使用户的生活更加轻松,可以在创建Detail对象时将Detail对象添加到Variant内联,因此必须在保存Product之前进行。

  • 有没有办法手动刷新内联值?
  • 我是否可以使用中间保存创建详细信息对象而不是产品并返回结果?
  • 模型应该重新设计吗? (我真的不想这样做,除非我必须这样做)
  • 用户在添加产品时需要遵循不同的工作流程吗?

我试图通过使用js将条目注入内联,但这是hackish,并且Django没有使用假值来验证formset抛出错误选择了错误的值。

在我写这个问题时,我想到了最后的想法。如果更改了对象的内联形式,则可以创建js,将数据传递给自定义视图,该视图将创建对象并返回结果。我看到的一个问题(旁边感觉不对)是如何通知django创建了新对象,因此它不会引发有关非现有值的错误。

无论如何,我希望有人能理解这个长期的问题。

2 个答案:

答案 0 :(得分:2)

我想到的一件事是Knockout.js

非常善于同时更新DOM中的大量元素,并且您可以使用来自客户端事件的Ajax调用轻松地将新值推回到自定义视图。

有几个框架可以做到这一点,但我认为Knockout是最容易阅读和实现最受欢迎的框架之一,如Backbone,Angular,Ember等。

Django通常会抱怨动态添加的选项,但只要在表单验证时它们存在于服务器端,你理论上 就可以了。

答案 1 :(得分:0)

我决定放弃这个想法,因为它花了很多时间,可能需要更多。我想出的也是相当讨厌的黑客而不是编码。但是不要把这个挂在这里,我会发布任何其他人的提示。

我有两个不同模型的模型作为内联formset,它们都有主模型的外键,其中一个有其他的外键。想法是根据用户输入的值在其中一个内联中创建虚假条目。正如它所代表的那样,使用jQuery与jango一起发布它很容易。所以我做了,但当然Django知道这个模型不存在。解决方法是创建我自己的表单和字段,并像我here一样覆盖clean()方法。

这导致了许多问题,其中一部分原因是我的模型依赖于彼此,而且必须切割一个clean()方法,以便不检查db对象是否存在。除此之外,在现场验证阶段缺乏有关POST数据的信息,因此必须覆盖表单的clean()方法,因为已发布数据。然而,它是不洁净的,因此必须从POST dict中提取并验证。此时我决定停止,因为它越来越复杂,可能导致数据不一致。我猜测下一步将是覆盖ModelAdmin的保存方法,因为创建的对象不在与formset绑定的查询集中,除非在可以完成的路上某个地方。

总结一下,我不得不说,在这一点上,我永远不会这样做,并使用我自己的change_form视图来更好地控制数据流。

TL;博士

创建自定义视图change_form。