使用unique_together约束django多对多关系

时间:2011-07-13 23:50:58

标签: mysql django-models django-orm

我认为这可能比Django更多的SQL,但Django就是我正在做的事情。我想要做的是想出一个对象模型,它可以有很多属性,但每个属性类型仅限于1个属性类型宾语。

假设我们有3种属性类型:

  • is_cool
  • is_happy
  • is_mean

假设我有一个对象(MyObject),它可以将*(0-All)这些属性应用于它,但只有一个属性。

所以我认为这是如下图所示(如果我错了请纠正我):

Object MySQL Diagram

在Django中,我正在努力解决这个问题。我希望它在db级别,即使用unique_together

这是我的......

PROP_VALUE_CHOICES = (("URL", "url"),
                      ("Boolean", "bool"),
                      ("String", "char"),
                      ("Person", "person"))

class PropertyType(models.Model):
    name = models.CharField(max_length=32)
    value_type = models.CharField(max_length=32, choices=PROP_VALUE_CHOICES)

class Property(models.Model):
    type = models.ForeignKey(PropertyType)
    value = models.CharField(max_length=32)

class MyObjectA(models.Model):
    properties = models.ManyToManyField(Property, related_name="MyObjectA")

class MyObjectB(models.Model):
    properties = models.ManyToManyField(Property, related_name="MyObjectB")

所以问题:

  1. 上面的图片是记录我想要完成的内容的正确方法。
  2. 我的模型不完整 - 我缺少什么,我在哪里对对象名称和属性类型应用unique together约束。
  3. 顺便说一句 - 这类似于this post,但他们使用的是我不确定需要的?

    谢谢!

1 个答案:

答案 0 :(得分:0)

如果有人真的在寻找这个答案......

使用Abstract Base Class我创建了以下应该有效的结构。当然,它不再完全代表图片,但确实解决了问题。

PROP_VALUE_CHOICES = (("URL", "url"),
                      ("Boolean", "bool"),
                      ("String", "char"),
                      ("Person", "person"))

class PropertyType(models.Model):
    name = models.CharField(max_length=32)
    value_type = models.CharField(max_length=32, choices=PROP_VALUE_CHOICES)

class Property(models.Model):
    type = models.ForeignKey(PropertyType, unique=True, related_name="%(app_label)s_%(class)s_related")
    value = models.CharField(max_length=32)

    class Meta:
        abstract = True

class ObjectAProperties(Property): pass

class ObjectA(models.Model):
    properties = models.ManyToManyField(Property, through="ObjectAProperties")

class ObjectBProperties(Property): pass

class ObjectB(models.Model):
    properties = models.ManyToManyField(Property, through="ObjectBProperties")

发布以防我将来再次需要这个!