Python 使用 django-rest-framework 序列化程序检索外键值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17280007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 00:56:34  来源:igfitidea点击:

Retrieving a Foreign Key value with django-rest-framework serializers

pythondjangodjango-rest-framework

提问by hellsgate

I'm using the django rest framework to create an API. I have the following models:

我正在使用 django rest 框架来创建 API。我有以下型号:

class Category(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name


class Item(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category, related_name='items')

    def __unicode__(self):
        return self.name

To create a serializer for the categories I'd do:

要为我要做的类别创建序列化程序:

class CategorySerializer(serializers.ModelSerializer):
    items = serializers.RelatedField(many=True)

    class Meta:
        model = Category

... and this would provide me with:

......这将为我提供:

[{'items': [u'Item 1', u'Item 2', u'Item 3'], u'id': 1, 'name': u'Cat 1'},
 {'items': [u'Item 4', u'Item 5', u'Item 6'], u'id': 2, 'name': u'Cat 2'},
 {'items': [u'Item 7', u'Item 8', u'Item 9'], u'id': 3, 'name': u'Cat 3'}]

How would I go about getting the reverse from an Item serializer, ie:

我将如何从 Item 序列化程序中获取反向信息,即:

[{u'id': 1, 'name': 'Item 1', 'category_name': u'Cat 1'},
{u'id': 2, 'name': 'Item 2', 'category_name': u'Cat 1'},
{u'id': 3, 'name': 'Item 3', 'category_name': u'Cat 1'},
{u'id': 4, 'name': 'Item 4', 'category_name': u'Cat 2'},
{u'id': 5, 'name': 'Item 5', 'category_name': u'Cat 2'},
{u'id': 6, 'name': 'Item 6', 'category_name': u'Cat 2'},
{u'id': 7, 'name': 'Item 7', 'category_name': u'Cat 3'},
{u'id': 8, 'name': 'Item 8', 'category_name': u'Cat 3'},
{u'id': 9, 'name': 'Item 9', 'category_name': u'Cat 3'}]

I've read through the docs on reverse relationshipsfor the rest framework but that appears to be the same result as the non-reverse fields. Am I missing something obvious?

我已经阅读了有关其余框架的反向关系的文档,但这似乎与非反向字段的结果相同。我错过了一些明显的东西吗?

采纳答案by Tom Christie

Just use a related field without setting many=True.

只需使用相关字段而不设置many=True.

Note that also because you want the output named category_name, but the actual field is category, you need to use the sourceargument on the serializer field.

请注意,还因为您想要名为 的输出category_name,但实际字段是category,所以您需要使用source序列化程序字段上的参数。

The following should give you the output you need...

以下应该给你你需要的输出......

class ItemSerializer(serializers.ModelSerializer):
    category_name = serializers.RelatedField(source='category', read_only=True)

    class Meta:
        model = Item
        fields = ('id', 'name', 'category_name')

回答by hsebastian

Another thing you can do is to:

您可以做的另一件事是:

  • create a property in your Itemmodel that returns the category name and
  • expose it as a ReadOnlyField.
  • 在您的Item模型中创建一个属性,返回类别名称和
  • 将其作为ReadOnlyField.

Your model would look like this.

你的模型看起来像这样。

class Item(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category, related_name='items')

    def __unicode__(self):
        return self.name

    @property
    def category_name(self):
        return self.category.name

Your serializer would look like this. Note that the serializer will automatically get the value of the category_namemodel property by naming the field with the same name.

您的序列化程序将如下所示。请注意,序列化程序将category_name通过命名具有相同名称的字段来自动获取模型属性的值。

class ItemSerializer(serializers.ModelSerializer):
    category_name = serializers.ReadOnlyField()

    class Meta:
        model = Item

回答by Sayok88

In the DRF version 3.6.3 this worked for me

在 DRF 版本 3.6.3 这对我有用

class ItemSerializer(serializers.ModelSerializer):
    category_name = serializers.CharField(source='category.name')

    class Meta:
        model = Item
        fields = ('id', 'name', 'category_name')

More info can be found here: Serializer Fields core arguments

更多信息可以在这里找到:Serializer Fields core arguments

回答by suhailvs

this worked fine for me:

这对我来说很好用:

class ItemSerializer(serializers.ModelSerializer):
    category_name = serializers.ReadOnlyField(source='category.name')
    class Meta:
        model = Item
        fields = "__all__"

回答by John Moutafis

Worked on 08/08/2018 and on DRF version 3.8.2:

在 08/08/2018 和 DRF 版本 3.8.2 上工作:

class ItemSerializer(serializers.ModelSerializer):
    category_name = serializers.ReadOnlyField(source='category.name')

    class Meta:
        model = Item
        read_only_fields = ('id', 'category_name')
        fields = ('id', 'category_name', 'name',)

Using the Meta read_only_fieldswe can declare exactly which fields should be read_only. Then we need to declare the foreignfield on the Meta fields(better be explicit as the mantra goes: zen of python).

使用 Metaread_only_fields我们可以准确地声明哪些字段应该是只读的。然后我们需要foreign在 Meta 上声明该字段fields(最好像口头禅那样明确:zen of python)。

回答by Anurag Misra

Simple solution source='category.name'where categoryis foreign key and .nameit's attribute.

简单的解决方案 source='category.name',其中category为外键和.name它的属性。

from rest_framework.serializers import ModelSerializer, ReadOnlyField
from my_app.models import Item

class ItemSerializer(ModelSerializer):
    category_name = ReadOnlyField(source='category.name')

    class Meta:
        model = Item
        fields = __all__