Home > Software design >  Access different serializer if a queryset is empty Django Rest Framework
Access different serializer if a queryset is empty Django Rest Framework

Time:09-30

I don't think I am implementing this correctly, but I am trying to change the serializer used for a queryset based on a condition (if there are no venues in one queryset, switch to another serializer and just return list object). I'm not quite sure how to do this.

Here is the view

class SavedVenuesViewSet(viewsets.ModelViewSet):
    serializer_class = UserVenueSerializer
    
    def get_queryset(self):
        list_id = self.request.GET.get('list_id', None)
        user = self.request.user.id
        print(user)
        print(list_id)
        print(type(list_id))
        qs = UserVenue.objects.filter(user_list=int(float(list_id)))
        if not qs:    
            print("EMPTY LIST") #this is where i try to switch serializer
            serializer_class = UserListSerializer
            return UserVenue.objects.filter(id=int(float(list_id)))
        else:
            return qs

Here are the relevant serializers:

class UserVenueSerializer(serializers.ModelSerializer):
    venue = mapCafesSerializer()
    
    class Meta:
        model = UserVenue
        fields = ['user', 'user_list', 'venue']
        depth = 2 

[...]

class UserListSerializer(serializers.ModelSerializer): 
    class Meta:
        model = UserList
        fields = ['id', 'user', 'list_name']
        depth = 2

The traceback isn't throwing an error but it isn't doing what I am hoping:

1
45
<class 'str'>
EMPTY LIST
[29/Sep/2021 11:05:36] "GET /api/savedvenues/?list_id=45 HTTP/1.1" 200 2

CodePudding user response:

You could remove serializer_class field from your view, and create get_serializer_class() method, that will contain the logic for choosing the serializer. Is the best practice.

But, you can also, do it in your get queryset.

First, remove serializer_class attribute from your view. Instead, set it inside your get_queryset method (with this.serializer_class);

def get_queryset(self):
    list_id = self.request.GET.get('list_id', None)
    qs = UserVenue.objects.filter(user_list=int(float(list_id)))
    if not qs:
        self.serializer_class = UserVenueSerializer  
        return UserVenue.objects.filter(id=int(float(list_id)))
    else:
        self.serializer_class = UserListSerializer
        return qs

Don't forget use the self.serializer_class.

CodePudding user response:

This is the correct practice to change serializer class in ModelViewSet:

You have to override get_serializesr_class method:

class SavedVenuesViewSet(viewsets.ModelViewSet):
    serializer_class = UserVenueSerializer
    
    def get_serializer_class(self):
        if not self.get_queryset():  # Check your conditions here
            return UserListSerializer
        else:
            return UserVenueSerializer
  • Related