6

你好,

在管理面板中,我创建了用于添加产品的表单。表单包括 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)

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

class DetailInline(admin.TabularInline):
    model = Detail

class VariantInline(admin.StackedInline):
    model = Variant

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

    inlines = [DetailInline, VariantInline]

这很好用,模型保存得很好,我对 Variants inline 有问题。内联变体显示 Detail 对象,但仅显示已保存在数据库中的对象。为了使用户的生活更轻松,最好在创建 Detail 对象时将 Detail 对象添加到 Variant inline,因此必须在保存 Product 之前发生。

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

我曾尝试使用 js 将条目注入内联,但这是 hackish 并且 Django 没有验证带有假值的表单集,抛出错误,即选择了错误的值。

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

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

4

2 回答 2

2

想到的一件事是Knockout.js

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

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

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

于 2013-02-19T00:46:49.353 回答
0

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

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

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

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

tl;博士

创建自定义视图 change_form。

于 2013-03-02T09:30:36.020 回答