在 Django 中使用 CreateView 创建复杂的多模型对象

Complex multi-model object creation with CreateView in Django

我有一个用户可以定义产品的设置(如 'MacBook Pro')。每个 Product 获得 "instantiated" 以创建一个物理项目 (ProductInstance),该项目获得一个序列号。到目前为止很简单。

我希望用户能够定义其他类型的唯一标识符,例如 MAC 地址、VIN、社会安全号码等。我称之为 UIDType。每个产品可以有零个或多个 UIDType。这些需要通过分配 name/description 并链接到 ProductUIDType (UIDProductInfo) 以某种方式加以区分。要实际分配值,我需要为特定 ProductInstanceUIDProductInfo 分配一个值——这是通过 UID 模型完成的。

当用户实例化一个产品(创建一个 ProductInstance)时,他们应该被强制为 Product 的每个 UIDProductInfo 创建一个并且只创建一个 UID他们正在实例化。我想在一个页面上完成所有操作。问题是:使用 CreateView,我该怎么做?

我想我需要 ProductInstanceModelForm 和处理 UID 的表单集。 UID 表单集中的表单需要创建一个 UID,它绑定到与 Product 关联的每个 UIDProductInfo 对象和新创建的 ProductInstance。不幸的是,我不知道该怎么做。在 CreateViewget_context_data 方法中创建表单集时,我尝试使用 initial 参数,以及其他一些更笨拙的方法,但我无法正确创建表单集。

感谢您的帮助。模型和我对 CreateView.get_context_data 方法的不幸尝试如下

型号:

# a product, i.e. Toyota Corolla
class Product(models.Model):
    name = models.CharField(max_length = 255)
    identifiers = models.ManyToManyField('UIDType', related_name = 'products', through = 'UIDProductInfo')

# a physical item, an "instantiation" of a Product. Gets a serial number
class ProductInstance(models.Model):
    serial_number = models.CharField(max_length = 255)
    product = models.ForeignKey(Product, related_name = 'instances')

# a type of unique identifier, like a MAC address
class UIDType(models.Model):
    name = models.CharField(max_length = 255, unique = True)

# a description of a UIDType as it applies to a particular Product.
# for example, a computer might get two MAC addresses, 'Host MAC 1' and 'Host MAC 2'
class UIDProductInfo(models.Model):
    name = models.CharField(max_length = 255)
    type = models.ForeignKey(UIDType, related_name = 'info')
    product = models.ForeignKey(Product, related_name = 'product_identifiers')

# a unique identifier for a ProductInstance
class UID(models.Model):
    value = models.CharField(max_length = 255)
    info = models.ForeignKey(UIDProductInfo, related_name = 'values')
    product_instance = models.ForeignKey(ProductInstance, related_name = 'identifiers')

get_context_data:

def get_context_data(self, **kwargs):
    self.object = None
    context = super(ProductInstanceCreate, self).get_context_data(**kwargs)

    product = get_object_or_404(Product, id = self.kwargs.get('product_pk'))

    uid_info = [ ]

    pi = ProductInstance(product = product)

    for info in pi.product.product_identifiers.all():
        uid = UID(productInstance = pi, id_type = info)
        uid_info.append({'info':uid})

    UIDFormset = inlineformset_factory(ProductInstance, UID,
            fields = ('identifier', 'info',), can_delete = False,
            widgets = { 'info' : HiddenInput() },
            labels = {'identifier' : ''}, extra = 3)

    uid_formset = UIDFormset(
            instance = pi,
            initial = uid_info
            )

    context['identifiers_formset'] = uid_formset

    return context

我已经使用这里描述的技术而不是使用表单集解决了这个问题:

https://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/