简体   繁体   中英

Django Rest Framework Return on User's Resources in Nested Serializer

I am trying to return just the user's resources in a nested serializer response. My current response looks like this:

{
    "id": 5174,
    "resourceName": "name here",
    "moreInformation": [
        {
            "id": 15924,
            "infoName": "stuff here",
            "infoDetails": [
                {
                    "id": 51,
                    "createdBy": 1,
                    "detail": "detail here",
                    "moreInformation": 15924
                },
                {
                    "id": 52,
                    "createdBy": 3,
                    "detail": "detail here",
                    "moreInformation": 15924
                }
            ]
        }
    ]
}

I'm trying to make it to where when the user GET s the ResourceName endpoint, that the infoDetails only shows the infoDetails that were createdBy that user. The current response returns all of the infoDetails regardless of the createdBy field.

I'm able to only return the infoDetail if the current user's id matches the createdBy id on the ListInfoDetails view, but not on the DetailResourceName view. Is there a way to do this on the serializer, or is it best to do it in the view?

Views:

class ListInfoDetail(generics.ListCreateAPIView):
    queryset = InfoDetail.objects.all()
    serializer_class = InfoDetailSerializer

    def get_queryset(self):
        user = self.request.user
        return user.infodetail_set.all()


class DetailResourceName(generics.RetrieveAPIView):
    queryset = ResourceName.objects.all()
    serializer_class = ResourceNameDetailSerializer

Serializers:

class InfoDetailSerializer(serializers.ModelSerializer):

    class Meta:
        model = InfoDetail
        fields = ['id', 'created_by', 'mnemonic_picture', 'block']


class MoreInformationSerializer(serializers.ModelSerializer):
    info_details = InfoDetailSerializer(source="infodetail_set", many=True, read_only=True)

    class Meta:
        model = MoreInformation
        fields = ['id', 'info_name', 'info_details']


class ResourceNameDetailSerializer(serializers.ModelSerializer):
    more_information = MoreInformationSerializer(many=True, read_only=True)

    class Meta:
        model = ResourceName
        fields = ['id', 'resourceName', 'more_information']

Models:

class MoreInformation(models.Model):
    info_name = models.CharField(max_length=200, unique=True)


class InfoDetail(models.Model):
    detail = models.TextField()
    more_information = models.ForeignKey(MoreInformation, on_delete=models.CASCADE)
    created_by = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)


class ResourceName(models.Model):
    resource_name = models.CharField(max_length=200, unique=True)
    more_information = models.ManyToManyField(MoreInformation)

Try this approach with a custom queryset on Prefetch :

from django.db.models import Prefetch


class DetailResourceName(generics.RetrieveAPIView):
    queryset = ResourceName.objects.all()
    serializer_class = ResourceNameDetailSerializer

    def get_queryset(self):
        return super().get_queryset().prefetch_related(
            Prefetch(
                "more_information__info_detail_set",
                queryset=InfoDetail.objects.filter(created_by=self.request.user),
            )
        )

This will filter all returned InfoDetail data based on the current user, from ResourceName 's related MoreInformation objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM