update tutorial queryset primarykeyrelatedfield framework foreign create python django django-rest-framework

python - tutorial - extra kwargs django rest



Incluir intermediario(a través del modelo) en las respuestas en Django Rest Framework (2)

Tengo una pregunta sobre el manejo de m2m / a través de modelos y su presentación en el marco de descanso django. Tomemos un ejemplo clásico:

models.py:

from django.db import models class Member(models.Model): name = models.CharField(max_length = 20) groups = models.ManyToManyField(''Group'', through = ''Membership'') class Group(models.Model): name = models.CharField(max_length = 20) class Membership(models.Model): member = models.ForeignKey(''Member'') group = models.ForeignKey(''Group'') join_date = models.DateTimeField()

serializers.py:

imports... class MemberSerializer(ModelSerializer): class Meta: model = Member class GroupSerializer(ModelSerializer): class Meta: model = Group

views.py:

imports... class MemberViewSet(ModelViewSet): queryset = Member.objects.all() serializer_class = MemberSerializer class GroupViewSet(ModelViewSet): queryset = Group.objects.all() serializer_class = GroupSerializer

Cuando OBTENGO una instancia de Miembro, recibo con éxito todos los campos de los miembros y también sus grupos; sin embargo, solo obtengo los detalles de los grupos, sin detalles adicionales que provienen del modelo de Membresía.

En otras palabras, espero recibir:

{ ''id'' : 2, ''name'' : ''some member'', ''groups'' : [ { ''id'' : 55, ''name'' : ''group 1'' ''join_date'' : 34151564 }, { ''id'' : 56, ''name'' : ''group 2'' ''join_date'' : 11200299 } ] }

Tenga en cuenta el join_date .

He intentado tantas soluciones, incluida, por supuesto, la página oficial de Django Rest-Framework al respecto y nadie parece dar una respuesta clara al respecto. ¿Qué debo hacer para incluir estos campos adicionales? Lo encontré más directo con django-tastypie pero tuve algunos otros problemas y prefiero rest-framework.


Estaba enfrentando este problema y mi solución (usando DRF 3.6) era usar SerializerMethodField en el objeto y consultar explícitamente la tabla de Membresía como sigue:

class MembershipSerializer(serializers.ModelSerializer): """Used as a nested serializer by MemberSerializer""" class Meta: model = Membership fields = (''id'',''group'',''join_date'') class MemberSerializer(serializers.ModelSerializer): groups = serializers.SerializerMethodField() class Meta: model = Member fields = (''id'',''name'',''groups'') def get_groups(self, obj): "obj is a Member instance. Returns list of dicts""" qset = Membership.objects.filter(member=obj) return [MembershipSerializer(m).data for m in qset]

Esto devolverá una lista de dicts para la clave de grupos donde cada dict se serializa desde MembershipSerializer. Para hacerlo modificable, puede definir su propio método de creación / actualización dentro de MemberSerializer donde iterará sobre los datos de entrada y creará o actualizará explícitamente las instancias del modelo de Membresía.


Qué tal si.....

En su MemberSerializer, defina un campo en él como:

groups = MembershipSerializer(source=''membership_set'', many=True)

y luego en su serializador de membresía puede crear esto:

class MembershipSerializer(serializers.HyperlinkedModelSerializer): id = serializers.Field(source=''group.id'') name = serializers.Field(source=''group.name'') class Meta: model = Membership fields = (''id'', ''name'', ''join_date'', )

Eso tiene el efecto general de crear un valor serializado, grupos, que tiene como fuente la membresía que desea, y luego utiliza un serializador personalizado para extraer los bits que desea mostrar.

EDITAR: como se comentó por @bryanph, serializers.field se renombró a serializers.ReadOnlyField en DRF 3.0, por lo que debería leer:

class MembershipSerializer(serializers.HyperlinkedModelSerializer): id = serializers.ReadOnlyField(source=''group.id'') name = serializers.ReadOnlyField(source=''group.name'') class Meta: model = Membership fields = (''id'', ''name'', ''join_date'', )

para cualquier implementación moderna