【问题标题】:Restricted ManyToMany relationships in DjangoDjango中受限的多对多关系
【发布时间】:2013-09-24 05:08:33
【问题描述】:

我希望有人能指出最 Djangoic 的方式来表示以下与模型的一般关系,以便 Django 现有的逻辑自然地强制执行这种关系。

事物 A 和事物 B 都具有多种类型之一。事物 A 可以与许多、一个或没有事物 B 相关,反之亦然(以对称方式),但是当且仅当它们共享相同的类型时,事物 A 和事物 B 才能相关。

我目前的实现是有三个模型,A、B 和 Type,其中 As 和 Bs 有一个 Type 的外键,A 和 B 有一个 m2m。

class A(models.Model):
    b = models.ForeignKey(B)
    typ = models.ManyToManyField(Type)

class B(models.Model):
    a = models.ForeignKey(A)

class Type(models.Model):
    name = models.CharField()

这让我可以做我想做的事,但并没有强制 A 不能有另一个类型的 B 的事实。我可以在我控制的视图中使用过滤逻辑,但是在我控制较少的地方,比如在 Admin 中,Django 让我将 As 映射到不同类型的 B。 Django中是否有另一种方式来表示As、Bs和Types之间的关系?

【问题讨论】:

    标签: django django-admin foreign-key-relationship m2m


    【解决方案1】:

    您是否将limit_choices_to 视为控制M2M 范围的一种方式?

    它可以使用 Q 对象进行复杂查询,但我猜不是 F 对象(对于复杂查询,包括父对象的当前状态),但如果不合适,您仍然可以让它拒绝保存

    【讨论】:

    • limit_choices_to 在定义模型时进行评估,而不查看特定模型实例的属性。我认为它不能用于检查具有相同类型的事物 A 的类型和 limit_choices_to 事物 B。
    【解决方案2】:

    这将是我的想法:

    class A(models.Model):
        typ = models.ManyToManyField(Type)
    
        @property
        def related2B(self)
            return list of relationships
    
        def save
            check that relationship is still valid if typ field changes
    
    class B(models.Model):
        typ = models.ManyToManyField(Type)
    
        @property
        def related2A(self)
            return list of relationships
    
        def save
            check that relationship is still valid if typ field changes
    
    class Type(models.Model):
        name = models.CharField()
    
    
    class Relationship(models.Model):
        classA = models.ForeignKey(A)
        classB = models.ForeignKey(B)
    
        def save
            do check that they share a type before saving
    

    【讨论】:

    • 模型保存方法不能做保存/不保存选择,这经常会导致相关项目保存问题。因为如果您没有 id 崩溃等情况,请保存相关对象。
    • 您可以将关系作为内联到 A 和 B,这将负责保存。在模型保存中,您只需要以正确的顺序获取保存:测试有效,调用 super 保存,现在您有了 id 并可以保存相关。
    猜你喜欢
    • 2021-09-11
    • 2011-08-22
    • 2011-06-02
    • 2012-02-26
    • 1970-01-01
    相关资源
    最近更新 更多