python - instalar - Recuperar un valor de clave externa con serializadores django-rest-framework
django rest framework with django 2 (5)
En la versión actual de DRF (3.6.3), esto funcionó para mí
class ItemSerializer(serializers.ModelSerializer):
category_name = serializers.CharField(source=''category.name'')
class Meta:
model = Item
fields = (''id'', ''name'', ''category_name'')
Estoy usando el marco de trabajo django para crear una API. Tengo los siguientes modelos:
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
Para crear un serializador para las categorías que haría:
class CategorySerializer(serializers.ModelSerializer):
items = serializers.RelatedField(many=True)
class Meta:
model = Category
... y esto me proporcionaría:
[{''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''}]
¿Cómo voy a obtener el reverso de un serializador de ítems, es decir:
[{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''}]
He leído los documentos sobre las relaciones inversas para el resto del marco, pero parece ser el mismo resultado que los campos que no son inversos. ¿Me estoy perdiendo algo obvio?
Esto funcionó bien para mi:
class ItemSerializer(serializers.ModelSerializer):
category_name = serializers.ReadOnlyField(source=''category.name'')
class Meta:
model = Item
fields = "__all__"
Otra cosa que puedes hacer es:
- crear una propiedad en su modelo de
Item
que devuelve el nombre de la categoría y - exponerlo como
ReadOnlyField
.
Tu modelo se vería así.
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
Su serializador se vería así. Tenga en cuenta que el serializador obtendrá automáticamente el valor de la propiedad del modelo category_name
nombrando el campo con el mismo nombre.
class ItemSerializer(serializers.ModelSerializer):
category_name = serializers.ReadOnlyField()
class Meta:
model = Item
Solo use un campo relacionado sin establecer many=True
.
Tenga en cuenta que también porque quiere que la salida se llame category_name
, pero el campo real es category
, debe usar el argumento source
en el campo del serializador.
Lo siguiente debería darle la salida que necesita ...
class ItemSerializer(serializers.ModelSerializer):
category_name = serializers.RelatedField(source=''category'', read_only=True)
class Meta:
model = Item
fields = (''id'', ''name'', ''category_name'')
Trabajó el 08/08/2018 y en DRF versión 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'',)
Utilizando Meta read_only_fields
podemos declarar exactamente qué campos deben ser read_only. Entonces tenemos que declarar el campo "extranjero" en los fields
Meta (mejor explíquese como dice el mantra: zen de python ).