【问题标题】:Using ManyToMany through correctly for complex model in django在 django 中正确使用 ManyToMany 来处理复杂模型
【发布时间】:2016-06-22 23:17:07
【问题描述】:

我的 django 应用中有一个半复杂的模型关系。

我有一个可以有多个地点的集团(一家企业) 所以

一个组也可以有许多提供者(人)。问题是,提供者通过组位置连接到特定组。也就是说,提供者可以拥有该位置。实际上,我相信提供商可以有许多位置(属于多个组)。到目前为止,我认为不正确的 django 中的方式是这样的:

class GroupLocations(models.Model):
    address_id = models.ForeignKey(Address, on_delete= models.SET_NULL)
    group_id = models.ForeignKey(Group, on_delete=models.SET_NULL)
    doing_business_as = models.CharField(max_length = 255)
    created_at=models.DateField(auto_now=false, auto_now_add=true)
    updated_at=models.DateField(auto_now=true, auto_now_add=true)

class ProviderLocations(models.Model):
    provider_id = models.ForeignKey(Provider, on_delete=models.CASCADE)
    group_location_id = models.ForeignKey(GroupLocations, on_delete=models.CASCADE)
    created_at=models.DateField(auto_now=false, auto_now_add=true)
    updated_at=models.DateField(auto_now=true, auto_now_add=true)

我的问题是,我的 Group(和/或 Provider)模型是否需要在其模型定义中指定某种关系?

class Group(models.Model):
    group_name = models.CharField(max_length=50)
    group_contact= models.CharField(max_length=50)
    #do I need something like the following:
   providers = models.ManyToMany(Provider, through='ProviderLocations')
   provider_locations = models.ManyToMany(Group, through='GroupLocations'


class Provider(models.Model):
    created_at=models.DateField(auto_now=false, auto_now_add=true)
    updated_at=models.DateField(auto_now=true, auto_now_add=true)
    groups = models.ManyToManyField(Group, through='GroupLocations')
    group_locations = models.ManyToMany(GroupLocations, through='ProviderLocations')

这样我就可以从提供商处获取群组列表以及群组位置 我可以从一个组中获取提供者列表和提供者位置。实际上更像是位置加入哪个位置。我仍在学习 Django 的关系系统,因此对如何使这些关系很好地协同工作的任何建设性批评都会有所帮助。

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    我的问题是,我的组(和/或提供商)模型是否需要 在他们的模型定义中指定了某种关系?

    是的,多对多关系。而且您只需要为一个模型或另一个模型定义它,因为可以双向遍历多对多。

    多对多关系的两端都可以自动访问 API 另一端。 API 就像“向后”的一对多一样工作 关系,如上。

    唯一的区别在于属性命名:定义的模型 ManyToManyField 使用该字段本身的属性名称, 而“反向”模型使用小写的模型名称 原始模型,加上'_set'(就像反向一对多 关系)。

    来源:https://docs.djangoproject.com/en/dev/topics/db/queries/#many-to-many-relationships

    因此您的模型可以被简化。

    class Group(models.Model):
       group_name = models.CharField(max_length=50)
       group_contact= models.CharField(max_length=50)
    
       providers = models.ManyToMany(Provider, through='ProviderLocations')
    
    
    class Provider(models.Model):
        created_at=models.DateField(auto_now=false, auto_now_add=true)
        updated_at=models.DateField(auto_now=true, auto_now_add=true)
    

    我不太清楚您为什么要同时创建 GroupLocationProviderLocation 模型。我确实相信它们可以合并。

    【讨论】:

    • 你可能是对的,我必须重新考虑这一点。我不确定该组将如何通过这些位置查看提供者(因为它们通过 group_locations 连接)。我相信我认为分离的原因是......提供者可能是一个群体的一部分,但在一个特定的位置。所以上面如果我理解的话:提供者将通过从上面的一行工作的提供者位置(它有一个组位置,它是如何返回到组)成为组的一部分?还是这就是您在提供者位置与组位置时所要求的?
    • 是的,这就是 ProviderLocation 或 GroupLocation 模型为您提供的。两者兼备意味着冗余。
    • 更改了我的评论。
    • 我不确定我是否完全理解了您的评论。例如,“提供者可能是组的一部分,但在特定位置”听起来并不像多对多
    • 也许通过他们工作的位置说它是一个提供者是一个组的一部分的好方法。一个组可以有很多位置。因此,提供者是特定位置的组的一部分。他们可能在许多团体地点工作,或者只在一个地点工作。但这就是它们之间的关系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 2012-11-23
    • 2020-03-29
    • 1970-01-01
    • 2012-06-12
    相关资源
    最近更新 更多