【问题标题】:In Django REST framework, how do you access a field in a table referenced by a foreign key在 Django REST 框架中,如何访问由外键引用的表中的字段
【发布时间】:2016-03-17 04:54:27
【问题描述】:

我在 Django 中有以下模型:

class campaign(models.Model):
    start_date = models.DateField('Start Date')
    end_date = models.DateField('End Date')
    description = models.CharField(max_length=500)
    name = models.CharField(max_length=200)
    active_start_time = models.TimeField()
    active_end_time = models.TimeField()
    last_updated = models.DateTimeField('Date updated',auto_now=True)
    active = models.BooleanField(default=True)
    client_id = models.ForeignKey('client',on_delete=models.PROTECT)
    def __unicode__(self):
            return u'%d | %s | %s' % (self.id,self.name, self.description)

class campaign_product(models.Model):
    product_id = models.ForeignKey('product',on_delete=models.PROTECT)
    last_updated = models.DateTimeField('Date updated',auto_now=True)
    campaign_id = models.ForeignKey('campaign',on_delete=models.PROTECT)

class product(models.Model):
    name = models.CharField(max_length=200)
    description = models.CharField(max_length=500)
    sku = models.CharField(max_length=200,blank=True,null=True)
    retail_price = models.DecimalField(decimal_places=2,max_digits=11)
    discount_price = ((1,'Yes'),(0,'No'))
    discounted_price = models.DecimalField(decimal_places=2,max_digits=11,blank=True,null=True)
    category_id = models.ForeignKey('category',on_delete=models.PROTECT)
    last_updated = models.DateTimeField('Date updated',auto_now=True)
    active = models.BooleanField(default=True)
    def __unicode__(self):
        return u'%d | %s' % (self.id, self.name)

我还有以下序列化器:

class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = campaign_product
        fields = ('product_id', 'campaign_id')

并且在 urls.py 文件中设置了如下视图:

class campaignProductViewSet(viewsets.ModelViewSet):
    queryset = campaign_product.objects.filter(campaign_id__start_date__lte=datetime.now(),campaign_id__end_date__gte=datetime.now(),campaign_id__active__exact=True)
    serializer_class = campaignProductSerializer

我的问题是,例如在http://127.0.0.1:8000/campaign_product/1/ 上发出请求时,我需要在查询结果中包含产品模型中的名称字段。当前,此请求仅返回 product_id 和 campaign_id。我尝试按如下方式制作序列化程序:

class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = campaign_product
        fields = ('product_id', 'campaign_id', 'product.name')

但随后服务返回以下错误:

Field name `product.name` is not valid for model `campaign_product`.

我尝试使用带引号和不带引号的 product__name。没有引号,它告诉我没有这样的变量,并且带有引号它给出了类似于上面的模型错误无效。高跟鞋!事实证明,获得这个额外的字段很痛苦:-(

【问题讨论】:

    标签: django python-2.7 django-rest-framework


    【解决方案1】:

    你想要的应该看起来更像这样:

    class campaignProductSerializer(serializers.HyperlinkedModelSerializer):
        product_name = serializers.CharField(source='product_id.name')
    
        class Meta:
            model = campaign_product
            fields = ('product_id', 'campaign_id', 'product_name')
    

    附:作为不相关的旁注,Python 代码中的惯例通常是使用 CamelCase 命名类,例如 CampaignCampaignProductProductCampaignProductSerializer

    编辑: P.P.S.最初,我用source='product.name' 写了product_name 字段。这实际上是由于我太快地查看代码并根据 Django 约定做出假设。通常,使用 Django ForeignKey,您将在您链接到的模型之后命名 ForeignKey 字段,而不是使用 _id 显式命名它。例如,CampaignProduct 模型通常用product = ForeignKey(...)campaign = ForeignKey(...) 编写。在后台,Django 实际上会使用product_idcampaign_id 作为数据库字段名称。您还可以访问模型实例上的这些名称。但是模型实例上的 productcampaign 变量实际上会返回您所指的对象。希望这一切都有意义。

    【讨论】:

    • 关闭但不完全在那里。现在,我在尝试获取序列化程序 campaignProductSerializer 上字段 product_name 的值时收到“出现属性错误。序列化程序字段可能命名不正确,并且与 campaign_product 实例上的任何属性或键都不匹配。原始异常文本为:' campaign_product' 对象没有属性 'product'。”
    • 谢谢,关于约定的说明...来自 java 背景。将在未来的python项目中进行调整。
    • 啊,我的错,我会在一分钟内更正答案以及另一个快速说明。此外,就样式约定而言,我强烈建议阅读 PEP 8,Python 样式指南。
    • 谢谢老兄,说得通。您甚至鼓励我根据您提到的约定进行调整。非常感谢!
    猜你喜欢
    • 2017-11-02
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多