web-dev-qa-db-ja.com

Django-rest-frameworkシリアライザーを使用した外部キ​​ー値の取得

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

私がするカテゴリのシリアライザーを作成するには:

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

    class Meta:
        model = Category

...そして、これは私に提供します:

[{'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'}]

アイテムシリアライザーからリバースを取得するにはどうすればいいですか、つまり:

[{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'}]

逆関係 の残りのフレームワークのドキュメントを読みましたが、それは非逆フィールドと同じ結果のようです。明らかな何かが欠けていますか?

51
hellsgate

many=Trueを設定せずに関連フィールドを使用するだけです。

また、category_nameという名前の出力が必要ですが、実際のフィールドはcategoryであるため、シリアライザーフィールドでsource引数を使用する必要があることに注意してください。

以下は、必要な出力を提供するはずです...

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

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

現在のDRF(3.6.3)バージョンでは、これでうまくいきました。

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

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

他にできることは:

  • カテゴリ名を返すItemモデルにプロパティを作成し、
  • ReadOnlyFieldとして公開します。

モデルは次のようになります。

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

シリアライザーは次のようになります。シリアライザは、フィールドに同じ名前を付けることで、category_nameモデルプロパティの値を自動的に取得することに注意してください。

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

    class Meta:
        model = Item
20
hsebastian

これは私のためにうまくいきました:

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

2018年8月8日および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',)

メタを使用するread_only_fieldsどのフィールドをread_onlyにするかを正確に宣言できます。次に、メタforeignfieldsフィールドを宣言する必要があります(マントラが進むにつれて明示する方が良いでしょう: zen of python )。

4
John Moutafis

シンプルなソリューション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__
2
Anurag Misra