class PropertyCategory(models.Model):
name = models.CharField(max_length=75)
def __unicode__(self):
return self.name
class Meta:
verbose_name = _('Property Category')
verbose_name_plural = _('Property Categories')
class Property(models.Model):
category = models.ForeignKey(PropertyCategory)
name = models.CharField(max_length=75)
def __unicode__(self):
return self.name
class Meta:
verbose_name_plural = 'Properties'
class Variant(models.Model):
properties = models.ManyToManyField(Property)
code = models.CharField(max_length=255)
def __unicode__(self):
product = Product.objects.get(variants__id=self.id)
return '%s (%s)' % (product.name, ', '.join([c.name for c in self.properties.all()]))
如何在创建/更新中验证我的Variant,它只能来自同一Property
的一个 PropertyCategory
。
假设我有这个产品; Lace-trim Cheeky Panty (Pink, XS)
,其中括号之间的属性是来自Properties
PropertyCategory
和Color
的{{1}}。我想限制Size
只能拥有每个Variant
中的一个,所以这样的事情不会发生;
PropertyCategory
除此之外,我想知道如果 允许有多个,可能会在Lace-trim Cheeky Panty (Pink, XS, Blue, M)
上设置一个特殊值。假设洗涤说明 可以 多次出现。我怎么能发现这种差异?
PropertyCategory
..但是,如果用户以后决定将class PropertyCategory(models.Model):
name = models.CharField(max_length=75)
multi_instance = models.BooleanField() # This determines if the Category's Properties can be applied more than once on a Variant
...
从multi_instance
设置为True
等,此功能可能会产生更多问题,因为它可能会破坏关系。
也许我可以使用False
延长正常PropertyCategory
?
答案 0 :(得分:1)
不幸的是,这是一个常见问题。即使properties
看起来像是Variant
的一部分,ManyToManyField
声明实际上也会导致创建一个引用Variants
和Properties
的全新表通过他们的主键。因此,当创建Variant
时,严格来说, no Properties
与之关联,因为只有在数据库中存在Variant
时才会发生这种情况。这就是为什么尝试通过覆盖Model.save()
方法(一种常见的第一种方法)来进行验证的原因是无效的。
同样,您可以通过覆盖Model.clean()
方法提供custom validation,但在调用此方法时(例如,通过ModelForm.is_valid()
),对象及其引用尚未被提及添加到数据库中。
如果您正在使用Django的表单(包括管理站点),请查看ModelForm validation。基本上,您将覆盖ModelForm的clean()
方法并验证表单而不是Model
本身。
关于你的第二个问题,你添加BooleanField
的想法听起来不错。如果您担心用户不当更改该值,则可以使用管理网站中的权限控制他们对PropertyCategories
的访问权限(或通过验证限制更改)。你是正确的,将值从True
更改为False
会产生问题,但这是一个概念问题,无论您选择何种方法实施,都是如此。