Home > database >  how to use objects.filter() for filtering a dictionary to a POST method in django rest framework
how to use objects.filter() for filtering a dictionary to a POST method in django rest framework

Time:10-19

Models.py

class Category(models.Model):
name = models.CharField(max_length=50,null=False, blank=False)

def __str__(self):
    return self.name

class Photo(models.Model):
category = models.ForeignKey(Category, on_delete= models.SET_NULL,related_name='category', null= True, blank= False)
image = models.ImageField(null= False, blank = False)
description = models.TextField(null=True, blank=True)

def __str__(self):
    return self.description

Serializers.py

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ['name']


class PhotoSerializer(serializers.ModelSerializer):
    category = CategorySerializer(many=False)
    class Meta:
        model = Photo
        fields = ['id','category','image','description']

view.py

from django.http import response
from rest_framework import viewsets
from rest_framework import serializers
from rest_framework.response import Response
from rest_framework.serializers import Serializer
from rest_framework.views import APIView
from .models import Category, Photo
from .serializers import PhotoSerializer


class DisplayAllViewSet(viewsets.ModelViewSet):
    queryset = Photo.objects.all()
    serializer_class = PhotoSerializer

class DisplayCategoryViseViewSet(APIView):
    serializer_class = PhotoSerializer

    def post(self, request, format=None):
        data = self.request.data
        print(data)
        category = data['category']
        print(category)
        print(category['name'])
        name=category['name']
        queryset = Photo.objects.filter(category=name)
        serializer = PhotoSerializer(queryset, many=True)
        return Response(Serializer.data)

urls.py

from re import I
from django.db import router
from django.urls import path
from django.conf.urls import include
from rest_framework import routers
from .views import DisplayAllViewSet, DisplayCategoryViseViewSet

router = routers.DefaultRouter()
router.register('allImages',DisplayAllViewSet)

urlpatterns = [
    path('', include(router.urls)),
    path('category',DisplayCategoryViseViewSet.as_view()),
]

In Postman : GET request http://127.0.0.1:8000/gallery/allImages

[
    {
        "id": 1,
        "category": {
            "name": "Sirsi"
        },
        "image": "http://127.0.0.1:8000/sunset.jpg",
        "description": "Sunset view point"
    },
    {
        "id": 2,
        "category": {
            "name": "Chickmangluru"
        },
        "image": "http://127.0.0.1:8000/tiger.jpg",
        "description": "cheeta"
    }
]

In Postman: POST request http://127.0.0.1:8000/gallery/category Body:

{
    "category":{
        "name":"Sirsi"
    }
}

ValueError : Field 'id' is expected a number but got 'Sirsi'

I am not able to map request data with filter(category=name) I know category is a Dict, But do we use Dict to map with name(Sirsi) in filter? to retrive the api using category wise.

Desired Outcome:

{
        "id": 1,
        "category": {
            "name": "Sirsi"
        },
        "image": "http://127.0.0.1:8000/sunset.jpg",
        "description": "Sunset view point"
    },

Thank you in advance :)

CodePudding user response:

In your post method of DisplayCategoryViseViewSet you need to make two changes as shown below. changes are added as comments in the code

class DisplayCategoryViseViewSet(APIView):
    serializer_class = PhotoSerializer
    
    def post(self, request, format=None):
        data = self.request.data
        print(data)
        category = data['category']
        print(category)
        print(category['name'])
        name=category['name']
        queryset = Photo.objects.filter(category__name=name) #Since you are passing name, if you are passing id of the category, you can give category=name
        print(queryset[0])
        serializer = PhotoSerializer(queryset, many=True)
        return Response(serializer.data)  #Typo , Serializer should be serializer
  • Related