Estoy tratando de cambiar el nombre del campo del modelo en el serializador DRF como alias en SQL. He probado diferentes métodos pero no he tenido éxito.
modelos.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')
También intenté agregar un alias en Django Queryset pero no puedo cambiar.
Actualizado
Esta es la excepción a la que me enfrento
AttributeError at / ViewName / 'module' object no tiene atributo 'Field'
¿Cómo puedo hacer esto?
django
django-rest-framework
Shoaib Ijaz
fuente
fuente
serializers.SerializerMethodField
enfoque? Quiero decir esto:serializers.SerializerMethodField('get_location')
ydef get_location(self, obj): ...
serializers.py
?Respuestas:
Puede utilizar
serializers.SerializerMethodField
:Aquí está el modelo Park, que tiene campos de nombre y nombre_alternativo.
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
Aquí está el serializador para el modelo Park, ParkSerializer. Esto cambia el nombre de alternate_name a location.
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
Además, puede usar
serializers.CharField
consource
atributo:class ParkSerializer(serializers.ModelSerializer): location = serializers.CharField(source='other_fields') class Meta: model = Park fields = ('other_fields', 'location')
La
__
notación de Django para atravesar la clave externa también funciona:location = serializers.CharField(source='OtherModel__other_fields')
El mismo principio se aplica si desea cambiar el tipo de retorno en la API, para que pueda hacerlo
serializers.DecimalField(source=...)
y también otros tipos de campo.Sin embargo, esto funcionaría solo para campos de solo lectura.
fuente
source
kwarg en su lugar como se describe a continuación.Hay una característica muy buena en los campos de serializador y en los serializadores en general llamada 'fuente' donde puede especificar la fuente de datos del campo de modelo.
class ParkSerializer(serializers.ModelSerializer): location = serializers.SomeSerializerField(source='alternate_name') class Meta: model = Park fields = ('other_fields', 'location')
Donde serializers.SomeSerializerField pueden ser serializers.CharField como sugiere su modelo pero también pueden ser por cualquiera de los otros campos. También puede poner campos relacionales y otros serializadores en su lugar y esto aún funcionaría a la perfección. es decir, incluso si alternate_name fuera un campo de clave externa para otro modelo.
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
Esto también funciona con la creación, eliminación y modificación de tipos de solicitudes. Crea efectivamente una asignación uno a uno del nombre de campo en el serializador y el nombre de campo en modelos.
fuente
source
es un enfoque más general. Pero puede ver algunos intentos de usarlo en la pregunta, por lo que si desea responder de esa manera, también debe aclarar por qué el código original no funciona, ¿no es así?locations = serializers.PrimaryKeyRelatedField(source='alternate_name', queryset=AlternateName.objects.all())
. Al parecer, tambiénRelatedField
se puede utilizar.Esto también funcionaría para operaciones de escritura
class ParkSerializer(serializers.ModelSerializer): location = serializers.CharField(source='alternate_name') class Meta: model = Park fields = ('id', 'name', 'location')
fuente