Skip to content
Advertisement

SearchFilter for multiple models — Django

Using Django 3.2 with Restframework. I’m trying for search filter and create a API with restframework which would output the searched term with its whole object.

I had a little success on that with official doc. But from that I can only search in a single Model and not as globally. I found a blog on how to use multiple Models together?

I tried for following from that:

Views.py

class GlobalSearchList(generics.ListAPIView):
    serializer_class = GlobalSearchSerializer

    def get_queryset(self):
      query = self.request.query_params.get('query', None)
      users = MasterUser.objects.filter(Q(firstname__icontains=query) | Q(lastname__icontains=query) | Q(email__icontains=query) | Q(category__icontains=query))
      webinar = MasterWebinar.objects.filter(Q(host__icontains=query) | Q(title__icontains=query))
      section = ResourceSection.objects.filter(Q(resource_name__icontains=query))
      item = SectionItem.objects.filter(Q(item_title__icontains=query))
      all_results = list(chain(users,webinar,section,item))
      serialize_obj = serializers.serialize('json',all_results)
      print(serialize_obj)    #Json response is printed in console
      return JsonResponse(json.loads(serialize_obj), safe=False)   #nothing as output

In here, while printing the output it does print a json object, but doesn’t return anything as output. Any cause why there is no output, where am I doing wrong?

serializers.py

class GlobalSearchSerializer(serializers.Serialize):
    
    def to_native(self, obj):
        if isinstance(obj, MasterIndividualMembers): 
            serializer = MasterIndividualMembersSerializer(obj)
        elif isinstance(obj, MasterUser):
            serializer = MasterUserSerializer(obj)
         elif isinstance(obj, MasterWebinar):
             serializer = MasterWebinarSerializer(obj)
         elif isinstance(obj, MasterResource):
             serializer = MasterResourceSerializer(obj)
         elif isinstance(obj, ResourceSection):
             serializer = ResourceSectionSerializer(obj)
         elif isinstance(obj, SectionItem):
             serializer = SectionItemSerializer(obj)

        else:
            raise Exception("Not found in any instance!")
        return serializer.data

Also I tried with serializers.ModelSerializer but it will only accept 1 model in serializer. Any suggestions please!

Edit: On testing in Postman I received following output:

Endpoint: localhost:8000/search/?query=john

[
    {}, {}
]

Expected outcome:

[
    {
        "id": 1,
        "password": "somehashcode",
        "last_login": "2021-07-13T06:08:08.313605Z",
        "email": "abc@xyz.com",
        "date_of_birth": "2020-10-10",
        "is_active": true,
        "is_admin": true,
        "firstname": "John",
        "lastname": "Doe",
        "is_member": true,
        "date_joined": "2021-07-11",
        "last_signed_in": "2021-07-11T03:27:37Z",
        "is_subscription": true,
        "category": null,
        "contact": "1231321",
        "membership_id": "343cr234rcrr3rc"
    },
    ...
    ...
]

To reproduce, console gives output: [<MasterUser: abc@xyz.com>, <MasterUser: dummy2@xyz.com>]

As the firstname has John the whole MasterUser came as output.

Advertisement

Answer

Eventually I get rid of class GlobalSearchList(generics.ListAPIView): and also its serializers.

and just add response as return HttpResponse(serialize_obj,content_type='application/json') to receive json response.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement