es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Existe una forma de especificar dinámicamente un queryset para una relación anidada (clase serializadora anidada) en Django Rest Framework?

Supongamos que tenemos dos modelos:

class Chapter(models.Model):
    title = models.CharField(maxlength=128)
    owner = models.ForeignKey(User, ondelete=models.CASCADE)

class Post(models.Model):
    title = models.CharField(maxlength=128)
    body = models.TextField()
    isarchived = models.BooleanField(default=False)
    chapter = models.ForeignKey(Chapter, on_delete=models.CASCADE)

Y el viewset predeterminado de ModelViewSet para el modelo Chapter:

class ChapterViewSet(viewsets.ModelViewSet):
    queryset = Chapter.objects.all()
    serializer_class = ChapterSerializer

Lo importante es que ChapterSerializer realiza una serialización anidada utilizando PostSerializer para proporcionar una clave post_set en la respuesta.

class PostSerializer(serializers.HyperlinkedModelSerializer):
    detailurl = HyperlinkedIdentityField(viewname='post-detail', read_only=True)

    class Meta:
        fields = ['id', 'title', 'is_archived', 'detail_url']
        model = Post


class ChapterSerializer(serializers.ModelSerializer):
    postset = PostSerializer(readonly=True, many=True)

    class Meta:
        model = Chapter
        fields = ['id', 'title', 'owner', 'post_set']

La pregunta es cómo puedo especificar dinámicamente un queryset para este PostSerializer anidado. Por ejemplo, cuando el usuario hace una solicitud GET, solo quiero incluir las publicaciones que no están archivadas (el campo is_archived está configurado en False) si el usuario que ha realizado la solicitud no es el propietario de un capítulo (request.user != current_chapter.owner). ¿Hay alguna forma de lograrlo?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible especificar dinámicamente un queryset para el PostSerializer anidado. Puede anular el método get_queryset de la clase PostSerializer y agregar una condición para filtrar las publicaciones en función del campo is_archived y el request.user:

    class PostSerializer(serializers.HyperlinkedModelSerializer):
        detail_url = HyperlinkedIdentityField(view_name='post-detail', read_only=True)
    
        class Meta:
            fields = ['id', 'title', 'is_archived', 'detail_url']
            model = Post
    
        def get_queryset(self):
            queryset = super().get_queryset()
            if self.context['request'].user != self.context['current_chapter'].owner:
                queryset = queryset.filter(is_archived=False)
            return queryset
    
    class ChapterSerializer(serializers.ModelSerializer):
        post_set = PostSerializer(read_only=True, many=True)
    
        class Meta:
            model = Chapter
            fields = ['id', 'title', 'owner', 'post_set']
    

Comments are closed.