【问题标题】:Adding one to many relationship in Django models在 Django 模型中添加一对多关系
【发布时间】:2019-09-05 08:00:44
【问题描述】:

我的 Django-REST 应用程序中有两个模型。

ProjectRequestContactRequest

我想做到,每个Projectrequest contains a list of the refered Contactrequests.

class ProjectRequest(models.Model):
project_name = models.CharField(max_length=50)
company_name = models.CharField(max_length=50)
#make array of technologiestechnologies = models.ArrayField(base_field=) (blank=True)
project_description = models.CharField(max_length=200)
project_type = models.CharField(max_length=30)
budget_estimation = models.IntegerField(
    default=1000,
    validators=[
    MinValueValidator(1800),
    MaxValueValidator(5000000)
])
#time_estimation = models.DateTimeField(default=None, blank=True, null=True)


class ContactRequest(models.Model):
topic = models.CharField(max_length=30)
description = models.CharField(max_length=200)
time = models.CharField(max_length=15)
project_request = models.ForeignKey(ProjectRequest, 
on_delete=models.CASCADE)

到目前为止,我已经使用外键建立了关系,到目前为止它工作正常。但是我想扩展功能,因此 ProjectRequest 包含所有项目请求的列表。我尝试了几个不同的字段,但没有任何运气,我只能找到ManyToManyOneToOne 的字段。如何实现?

【问题讨论】:

  • 你在使用 Django Rest 框架吗?
  • 是的,但我认为它不会改变模型结构?
  • ProjectRequest contains a list of all the projectrequestProjectRequest contains a list of all the contactrequest :) ?
  • 抱歉给您带来了困惑。ProjectRequest contains a list of all the contactrequest
  • 外键 is 是建立一对多关系的正确方法。但是,我认为您可能希望将 related_name 传递给您的外键字段,例如 project_request = models.ForeignKey(ProjectRequest, related_name="contacts") (不要忘记在进行此编辑后添加迁移) - 然后您可以访问项目中的所有相关联系请求使用ProjectRequest.objects.get(project_name="something").contacts.all() 请求

标签: python django model one-to-many


【解决方案1】:

有很多方法可以实现您想要的。为此,让我们在名为 contact_requests 的模型中添加一个 reverse relation

project_request = models.ForeignKey(ProjectRequest, on_delete=models.CASCADE, related_name="contact_requests")

现在您可以使用PrimaryKeyRelatedField 显示附加到每个ProjectRequestContactRequest 的主键。

class ProjectRequestSerializer(serializers.ModelSerializer):
    contact_requests = serializers.PrimaryKeyRelatedField(many=True, read_only=True)

    class Meta:
        model = ProjectRequest
        fields = ('contact_requests', 'company_name', ...)  # other fields 

或者如果你想要每个contact_requests的所有值,那么你可以像这样使用nested relationship

class ProjectRequestSerializer(serializers.ModelSerializer):
    contact_requests = ContactRequestSerializer(many=True, read_only=True)

    class Meta:
        model = ProjectRequest
        fields = ('contact_requests', 'company_name', ...) # and so on

【讨论】:

    【解决方案2】:

    您可以向 ProjectRequest 类添加一个属性函数,该函数会像这样重新运行与该 ProjectRequest 相关的所有 ContactRequest...

    class ProjectRequest(models.Model):
        project_name = models.CharField(max_length=50)
        company_name = models.CharField(max_length=50)
        #make array of technologiestechnologies = models.ArrayField(base_field=) (blank=True)
        project_description = models.CharField(max_length=200)
        project_type = models.CharField(max_length=30)
        budget_estimation = models.IntegerField(
            default=1000,
            validators=[
            MinValueValidator(1800),
            MaxValueValidator(5000000)
        ])
        #time_estimation = models.DateTimeField(default=None, blank=True, null=True)
    
        @property
        def contact_requests(self):
            return ContactRequest.objects.filter(project_request=self)
    
    
    class ContactRequest(models.Model):
        topic = models.CharField(max_length=30)
        description = models.CharField(max_length=200)
        time = models.CharField(max_length=15)
        project_request = models.ForeignKey(ProjectRequest, 
        on_delete=models.CASCADE)
    

    【讨论】:

    • 我会给你一个赞成票,作为答案,但我认为更好的方法是将类添加到序列化程序中,就像上面建议的那样:)
    【解决方案3】:

    我也有这个问题。我就是这样解决的:

    ContactRequest= models.ManyToManyField(ContactRequest,related_name="+")
    

    【讨论】:

      猜你喜欢
      • 2011-07-03
      • 2019-05-09
      • 2018-01-04
      • 2012-12-04
      • 1970-01-01
      • 1970-01-01
      • 2018-04-04
      • 2014-05-20
      • 2012-07-28
      相关资源
      最近更新 更多