모델을 직렬화하고 싶지만 직렬화 할 모델 인스턴스에서 일부 데이터베이스 조회를 수행해야하는 추가 필드를 포함하고 싶습니다.
class FooSerializer(serializers.ModelSerializer):
my_field = ... # result of some database queries on the input Foo object
class Meta:
model = Foo
fields = ('id', 'name', 'myfield')
이것을하는 올바른 방법은 무엇입니까? 나는 것을 볼 당신이 여분의 “상황”에 전달할 수 있습니다 상황에 맞는 사전에 추가 필드에 통과 할 수있는 권리 대답은, 시리얼에? 이 방법을 사용하면 필요한 필드를 가져 오는 논리가 serializer 정의와 함께 포함되지 않으며 이는 모든 직렬화 된 인스턴스가 필요하기 때문에 이상적입니다 my_field
. 다른 곳 DRF 시리얼 설명서는 말한다 “추가 필드가 모델에 어떤 속성이나 호출에 해당 할 수 있습니다.” 내가 말하는 것이 추가 필드입니까? 값 Foo
을 반환하는 모델 정의 에서 함수를 정의해야 my_field
하며 직렬 변환기에서 my_field를 해당 호출 가능 항목에 연결해야합니까? 그것은 어떻게 생겼습니까?
미리 감사드립니다. 필요한 경우 질문을 명확하게 설명하십시오.
답변
SerializerMethodField가 찾고있는 것 같습니다.
class FooSerializer(serializers.ModelSerializer):
my_field = serializers.SerializerMethodField('is_named_bar')
def is_named_bar(self, foo):
return foo.name == "bar"
class Meta:
model = Foo
fields = ('id', 'name', 'my_field')
http://www.django-rest-framework.org/api-guide/fields/#serializermethodfield
답변
이 방법으로 모델 방법을 속성으로 변경하고 serializer에서 사용할 수 있습니다.
class Foo(models.Model):
. . .
@property
def my_field(self):
return stuff
. . .
class FooSerializer(ModelSerializer):
my_field = serializers.ReadOnlyField(source='my_field')
class Meta:
model = Foo
fields = ('my_field',)
편집 : 최신 버전의 나머지 프레임 워크 (3.3.3을 시도 했음)를 사용하면 속성을 변경할 필요가 없습니다. 모델 방법은 잘 작동합니다.
답변
Django Rest Framework의 마지막 버전에서는 추가하려는 필드 이름으로 모델에 메소드를 작성해야합니다. 대한 필요가 없습니다 @property
및 source='field'
오류를 발생시킵니다.
class Foo(models.Model):
. . .
def foo(self):
return 'stuff'
. . .
class FooSerializer(ModelSerializer):
foo = serializers.ReadOnlyField()
class Meta:
model = Foo
fields = ('foo',)
답변
비슷한 질문 ( here )에 대한 나의 대답 이 유용 할 수 있습니다.
다음과 같은 방법으로 모델 방법을 정의한 경우 :
class MyModel(models.Model):
...
def model_method(self):
return "some_calculated_result"
상기 메소드를 호출 한 결과를 시리얼 라이저에 다음과 같이 추가 할 수 있습니다.
class MyModelSerializer(serializers.ModelSerializer):
model_method_field = serializers.CharField(source='model_method')
ps 사용자 정의 필드는 실제로 모델의 필드가 아니므로 일반적으로 다음과 같이 읽기 전용으로 만들고 싶습니다.
class Meta:
model = MyModel
read_only_fields = (
'model_method_field',
)
답변
추가 필드에서 읽고 쓰려면 직렬화기를 확장하는 새로운 사용자 정의 직렬화기를 사용할 수 있습니다.
class ExtraFieldSerializer(serializers.Serializer):
def to_representation(self, instance):
# this would have the same as body as in a SerializerMethodField
return 'my logic here'
def to_internal_value(self, data):
# This must return a dictionary that will be used to
# update the caller's validation data, i.e. if the result
# produced should just be set back into the field that this
# serializer is set to, return the following:
return {
self.field_name: 'Any python object made with data: %s' % data
}
class MyModelSerializer(serializers.ModelSerializer):
my_extra_field = ExtraFieldSerializer(source='*')
class Meta:
model = MyModel
fields = ['id', 'my_extra_field']
나는 이것을 사용자 정의 로직과 관련된 중첩 필드에서 사용합니다.
답변
이것은 나를 위해 일한
우리가 ModelSerializer에 추가 필드를 추가 할 .If, 우리는 필드가 조회의 일부 계산 후 약간의 발을 할당 할 수 아래도 좋아 할 수 있습니다. 또는 API 응답으로 매개 변수를 보내려는 경우가 있습니다.
model.py에서
class Foo(models.Model):
"""Model Foo"""
name = models.CharField(max_length=30, help_text="Customer Name")
**
serializer.py에서
**
class FooSerializer(serializers.ModelSerializer):
retrieved_time = serializers.SerializerMethodField()
@classmethod
def get_retrieved_time(self, object):
"""getter method to add field retrieved_time"""
return None
class Meta:
model = Foo
fields = ('id', 'name', 'retrieved_time ')
**
이것이 누군가를 도울 수 있기를 바랍니다.
**