Tengo una pregunta sobre cómo tratar con modelos m2m / through y su presentación en el marco de descanso de django. Tomemos un ejemplo clásico:
modelos.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 del miembro 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 probado tantas soluciones, incluida, por supuesto, la página oficial de Django Rest-Framework al respecto y nadie parece dar una respuesta clara y adecuada al respecto: ¿qué debo hacer para incluir estos campos adicionales? Lo encontré más sencillo con django-deliciouspie pero tuve algunos otros problemas y prefiero rest-framework.
Respuestas:
Qué tal si.....
En su MemberSerializer, defina un campo en él como:
y luego en su serializador de membresía puede crear esto:
Eso tiene el efecto general de crear un valor serializado, grupos, que tiene como origen la membresía que desea, y luego usa un serializador personalizado para extraer los bits que desea mostrar.
EDITAR: como lo comentó @bryanph,
serializers.field
se renombróserializers.ReadOnlyField
en DRF 3.0, por lo que debería leer:para cualquier implementación moderna
fuente
membership_set
es el nombre relacionado predeterminado para Miembro -> MembresíaEstaba 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 así:
Esto devolverá una lista de dictados para la clave de grupos donde cada dictado se serializa desde MembershipSerializer. Para que se pueda escribir, puede definir su propio método de creación / actualización dentro de MemberSerializer, donde itera sobre los datos de entrada y crea o actualiza explícitamente las instancias del modelo de membresía.
fuente
NOTA: Como ingeniero de software, me encanta usar arquitecturas y he trabajado profundamente en el enfoque por capas para el desarrollo, así que voy a responder con respeto a los niveles.
Como entendí el problema, aquí está la solución models.py
serializers.py
CustomModels.py
BusinessLogic.py
Técnicamente, tendría que pasar la solicitud a DataAccessLayer que devolvería los objetos filtrados de la capa de acceso a datos, pero como tengo que responder la pregunta de manera rápida, ¡ajusté el código en la capa de lógica empresarial!
fuente