Próbuję zmienić nazwę pola modelu w serializatorze DRF, jak alias w języku SQL. Próbowałem różnych metod, ale nie mogę.
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')
Próbowałem również dodać alias w Django Queryset, ale nie mogę tego zmienić.
Zaktualizowano
To jest wyjątek, przed którym stoję
AttributeError at / ViewName / obiekt „module” nie ma atrybutu „Field”
Jak mogę to zrobić?
django
django-rest-framework
Shoaib Ijaz
źródło
źródło
serializers.SerializerMethodField
podejścia? Mam na myśli to:serializers.SerializerMethodField('get_location')
idef get_location(self, obj): ...
serializers.py
?Odpowiedzi:
Możesz użyć
serializers.SerializerMethodField
:Oto model Park, który ma pola name i alternate_name.
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
Oto Serializer for Park Model, ParkSerializer. Spowoduje to zmianę nazwy alternate_name na lokalizację.
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
Dodatkowo możesz użyć
serializers.CharField
zsource
atrybutem:class ParkSerializer(serializers.ModelSerializer): location = serializers.CharField(source='other_fields') class Meta: model = Park fields = ('other_fields', 'location')
Zapis Django
__
do przechodzenia przez klucz obcy również działa:location = serializers.CharField(source='OtherModel__other_fields')
Ta sama zasada ma zastosowanie, jeśli chcesz zmienić typ zwracania w interfejsie API, więc możesz to zrobić
serializers.DecimalField(source=...)
a także inne typy pól.Działa to jednak tylko w przypadku pól tylko do odczytu.
źródło
source
Zamiast tego użyj kwarg, jak opisano poniżej.Istnieje bardzo fajna funkcja w polach serializatorów i serializatorach ogólnie nazywana „źródłem”, w której można określić źródło danych z pola modelu.
class ParkSerializer(serializers.ModelSerializer): location = serializers.SomeSerializerField(source='alternate_name') class Meta: model = Park fields = ('other_fields', 'location')
Gdzie serializers.SomeSerializerField może być serializers.CharField, jak sugeruje twój model, ale może również być przez dowolne inne pola. Możesz także zamiast tego umieścić pola relacyjne i inne serializatory, a to nadal będzie działać jak urok. tj. nawet jeśli alternate_name było polem klucza obcego w innym modelu.
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
Działa to również przy tworzeniu, usuwaniu i modyfikowaniu żądań. Skutecznie tworzy mapowanie jeden do jednego nazwy pola w serializatorze i nazwę pola w modelach.
źródło
source
jest bardziej ogólne podejście. Ale w pytaniu widać kilka prób użycia go, więc jeśli chcesz odpowiedzieć w ten sposób, powinieneś również wyjaśnić, dlaczego oryginalny kod nie działa, prawda?locations = serializers.PrimaryKeyRelatedField(source='alternate_name', queryset=AlternateName.objects.all())
. NajwyraźniejRelatedField
można go również użyć.To zadziała również dla operacji zapisu
class ParkSerializer(serializers.ModelSerializer): location = serializers.CharField(source='alternate_name') class Meta: model = Park fields = ('id', 'name', 'location')
źródło