Django REST Framework에서 필드 이름을 변경하는 방법


98

SQL의 별칭과 같은 DRF Serializer의 모델 필드 이름을 변경하려고합니다. 나는 다른 방법을 시도했지만 성공할 수 없습니다.

models.py

class Park(models.Model):
    name = models.CharField(max_length=256)
    alternate_name = models.CharField(max_length=256, blank=True)
    objects = models.GeoManager()

    class Meta:
        db_table = u'p_park'

    def __unicode__(self):
        return '%s' % self.name

    def alias_alternate_name(self):
        return self.alternate_name

serializers.py

class ParkSerializer(serializers.ModelSerializer):

    location = serializers.Field(source='alias_alternate_name')
    #location = serializers.SerializerMethodField(source='alias_alternate_name')

    #alternate_name as location


    class Meta:
        model = Park
        fields = ('id', 'name', 'location')

또한 Django Queryset에 별칭을 추가하려고 시도했지만 변경할 수 없습니다.

업데이트 됨

이것은 내가 직면 한 예외입니다.

/ ViewName / '모듈'개체의 AttributeError에 '필드'속성이 없습니다.

어떻게 할 수 있습니까?


1
serializers.SerializerMethodField접근 방식 의 올바른 구현을 사용하고 있습니까? 내 말은 : serializers.SerializerMethodField('get_location')그리고def get_location(self, obj): ...
erthalion 2014-04-09

수입품을 볼 수 있습니까 serializers.py?
joerick 2014

영업 이익 대신에 아래 더 나은 사람의 일부 잘못과 혼란 답을 인정하기 때문에 ... 질문을 downvote 것
NeuronQ

답변:


58

다음을 사용할 수 있습니다 serializers.SerializerMethodField.

다음은 이름 및 alternate_name 필드 가있는 모델 Park입니다.

class Park(models.Model):
    name = models.CharField(max_length=256)
    alternate_name = models.CharField(max_length=256, blank=True)
    objects = models.GeoManager()

    class Meta:
        db_table = u'p_park'

    def __unicode__(self):
        return '%s' % self.name

다음은 Park Model 용 Serializer , ParkSerializer입니다. 그러면 alternate_name의 이름이 위치로 변경됩니다.

class ParkSerializer(serializers.ModelSerializer):
    location = serializers.SerializerMethodField('get_alternate_name')

    class Meta:
        model = Park
        fields = ('other_fields', 'location')

    def get_alternate_name(self, obj):
        return obj.alternate_name

또한 다음 속성 serializers.CharField과 함께 사용할 수 있습니다 source.

class ParkSerializer(serializers.ModelSerializer):
    location = serializers.CharField(source='other_fields')

    class Meta:
        model = Park
        fields = ('other_fields', 'location')

__외래 키를 탐색하는 Django의 표기법도 작동합니다.

location = serializers.CharField(source='OtherModel__other_fields')

API에서 반환 유형을 변경하려는 경우에도 동일한 원칙이 적용되므로 serializers.DecimalField(source=...)다른 필드 유형도 수행 할 수 있습니다.

그러나 이것은 읽기 전용 필드에서만 작동합니다.


이제이 예외가 / view 이름 / '모듈'개체에 AttributeError를 던지고 아무런 속성 'SerializerMethodField'가 없다
Shoaib Ijaz

1
요청을 만들고 편집하는이 운동은 어떻게 될까요?
iankit

1
'Zen of Python'의 13 번 행 : "한 가지, 바람직하게는 한 가지 분명한 방법이 있어야합니다."
iankit

14
이것은 받아 들여진 대답이되어서는 안됩니다. 제가이 글을 쓰는 시점에 거의 5 배 많은 찬성표를 가지고있는 아래를보세요.
cderwin

6
이것은 나쁜 해결책입니다. source아래 설명 된대로 대신 kwarg를 사용하십시오 .
Patrick

215

serializer 필드와 serializer에는 일반적으로 'source'라는 매우 멋진 기능이 있습니다. 여기서 모델 필드의 데이터 소스를 지정할 수 있습니다.

class ParkSerializer(serializers.ModelSerializer):
    location = serializers.SomeSerializerField(source='alternate_name')

    class Meta:
        model = Park
        fields = ('other_fields', 'location')

여기서 serializers.SomeSerializerField는 모델이 제안한대로 serializers.CharField가 될 수 있지만 다른 필드에서도 가능합니다. 또한 관계형 필드 및 기타 직렬 변환기를 대신 넣을 수 있으며 여전히 매력처럼 작동합니다. 즉, alternate_name이 다른 모델에 대한 외래 키 필드 인 경우에도 마찬가지입니다.

class ParkSerializer(serializers.ModelSerializer):
    locations = AlternateNameSerializer(source='alternate_name', many=true)

    class Meta:
        model = Park
        fields = ('other_fields', 'locations')

class AlternateNameSerializer(serializers.ModelSerialzer):
    class Meta:
        model = SomeModel

이것은 요청의 생성, 삭제 및 수정 유형에도 적용됩니다. 직렬화 기의 필드 이름과 모델의 필드 이름의 일대일 매핑을 효과적으로 생성합니다.


나는 그것이 source더 일반적인 접근 방식 이라고 동의했습니다 . 그러나 질문에서 그것을 사용하려는 시도는 거의 볼 수 없으므로 그렇게 대답하고 싶다면 원래 코드가 작동하지 않는 이유를 분명히해야하지 않습니까?
erthalion

귀하의 코드는 정상적으로 작동합니다. 요청이 목록 및 검색
용인 한

두 답변 모두 불완전합니다. 외래 키의 경우이 방법은 새 Park를 만들 때 전체 부모 개체 (alternate_name)를 POST 요청의 dict로 제공해야 함을 의미합니다. 이는 부모 개체가 이미 존재하기 때문에 미친 짓입니다. ID를 통해 외부 인스턴스를 언급 할 수 있어야합니다.
stelios

제 경우에는 (외래 키)이 문제를 locations = serializers.PrimaryKeyRelatedField(source='alternate_name', queryset=AlternateName.objects.all()). 분명히 RelatedField사용할 수 있습니다.
stelios

@chefarov source = 'new_name'은 serializer 필드, 관계 및 기타 관련 serializer 등에 제공 할 수있는 일반적인 인수입니다. 대답이 불완전하다고 말하는 이유가 확실하지 않습니다.
iankit

15

이것은 쓰기 작업에서도 작동합니다.

class ParkSerializer(serializers.ModelSerializer):
    location = serializers.CharField(source='alternate_name')

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