在 Django 中使用 CreateView 创建复杂的多模型对象
Complex multi-model object creation with CreateView in Django
我有一个用户可以定义产品的设置(如 'MacBook Pro')。每个 Product
获得 "instantiated" 以创建一个物理项目 (ProductInstance
),该项目获得一个序列号。到目前为止很简单。
我希望用户能够定义其他类型的唯一标识符,例如 MAC 地址、VIN、社会安全号码等。我称之为 UIDType
。每个产品可以有零个或多个 UIDType
。这些需要通过分配 name/description 并链接到 Product
和 UIDType
(UIDProductInfo
) 以某种方式加以区分。要实际分配值,我需要为特定 ProductInstance
的 UIDProductInfo
分配一个值——这是通过 UID
模型完成的。
当用户实例化一个产品(创建一个 ProductInstance
)时,他们应该被强制为 Product
的每个 UIDProductInfo
创建一个并且只创建一个 UID
他们正在实例化。我想在一个页面上完成所有操作。问题是:使用 CreateView
,我该怎么做?
我想我需要 ProductInstance
的 ModelForm
和处理 UID 的表单集。 UID
表单集中的表单需要创建一个 UID
,它绑定到与 Product
关联的每个 UIDProductInfo
对象和新创建的 ProductInstance
。不幸的是,我不知道该怎么做。在 CreateView
的 get_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/
我有一个用户可以定义产品的设置(如 'MacBook Pro')。每个 Product
获得 "instantiated" 以创建一个物理项目 (ProductInstance
),该项目获得一个序列号。到目前为止很简单。
我希望用户能够定义其他类型的唯一标识符,例如 MAC 地址、VIN、社会安全号码等。我称之为 UIDType
。每个产品可以有零个或多个 UIDType
。这些需要通过分配 name/description 并链接到 Product
和 UIDType
(UIDProductInfo
) 以某种方式加以区分。要实际分配值,我需要为特定 ProductInstance
的 UIDProductInfo
分配一个值——这是通过 UID
模型完成的。
当用户实例化一个产品(创建一个 ProductInstance
)时,他们应该被强制为 Product
的每个 UIDProductInfo
创建一个并且只创建一个 UID
他们正在实例化。我想在一个页面上完成所有操作。问题是:使用 CreateView
,我该怎么做?
我想我需要 ProductInstance
的 ModelForm
和处理 UID 的表单集。 UID
表单集中的表单需要创建一个 UID
,它绑定到与 Product
关联的每个 UIDProductInfo
对象和新创建的 ProductInstance
。不幸的是,我不知道该怎么做。在 CreateView
的 get_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/