django-rest-framework serializer로 외래 키 값 검색


89

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

Item serializer에서 반대로 가져 오는 방법은 다음과 같습니다.

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

나머지 프레임 워크에 대한 역관계에 대한 문서를 읽었 지만 역전이 아닌 필드와 동일한 결과로 보입니다. 나는 명백한 것을 놓치고 있습니까?

답변:


85

설정하지 않고 관련 필드를 사용하십시오 many=True.

또한라는 출력을 원 category_name하지만 실제 필드는 category이므로 sourceserializer 필드 의 인수 를 사용해야합니다 .

다음은 필요한 출력을 제공해야합니다.

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

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

21
카테고리 모델의 모든 필드를 검색하는 것은 어떻습니까 ??
AJ

12
범주 모델의 모든 필드를 검색하려면 범주 serializer를 만들고 category_name = CategorySerliazer ()
Faizan Ali

7
난하지만 난이 오류가있어이 작업을 수행하려고 Relational field must provide a 'queryset' argument, or set read_only='True'
ePascoal

또는 다음과 같이 작성 / 업데이트를 지원하려면 queryset 속성을 제공 category_name = serializers.RelatedField(source='category', queryset=Category.objects.all()) 하십시오.
stelios

1
당신은 얻을 경우 AssertionError:...이 응답 사용 stackoverflow.com/a/44530606/5403449
조쉬

86

DRF 버전 3.6.3에서 이것은 나를 위해 일했습니다.

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

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

더 많은 정보는 여기에서 찾을 수 있습니다 : Serializer Fields core arguments


이 NoneType 오류 던졌다 항목 모델에서 카테고리 필드가 공백으로 설정하는 경우는 원인하지만 도자기가 될 필요는 진정한 =
사막의 낙타에게

29

또 다른 방법은 다음과 같습니다.

  • 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

직렬 변환기는 다음과 같습니다. serializer는 category_name동일한 이름의 필드 이름을 지정하여 모델 속성 의 값을 자동으로 가져옵니다 .

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

    class Meta:
        model = Item

18

이것은 나를 위해 잘 작동했습니다.

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

9

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',)

Meta를 사용하면 read_only_fields어떤 필드가 읽기 전용인지 정확하게 선언 할 수 있습니다. 그런 다음 foreign메타에 필드 를 선언해야합니다 fields(만트라가 진행되는대로 명시 적으로 더 잘 설명 : zen of python ).


6

외래 키와 속성 이 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__"

0

이 솔루션은 소스 모델을 정의 할 필요가 없기 때문에 더 좋습니다. 그러나 serializer 필드의 이름은 외래 키 필드 이름과 동일해야합니다.

class ItemSerializer(serializers.ModelSerializer):
    category = serializers.SlugRelatedField(read_only=True, slug_field='title')

    class Meta:
        model = Item
        fields = ('id', 'name', 'category')
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.