PereCullera
PereCullera

Reputation: 177

Django api rest filter manytomany

I am a quite New in Django and Django Api Rest FrameWork

I am trying to develop an Api with two models relationated with a ManyToMany relation

models.py

class Category(models.Model):
    name = models.CharField(max_length=100)

class Apartment(models.Model):
    id_2 = models.IntegerField(default= None)
    neighborhood = models.CharField(max_length=100)
    name = models.CharField(max_length=120)
    district = models.CharField(max_length=120)
    created = models.DateTimeField()
    cats = models.ManyToManyField(Category)
    address = models.CharField(max_length=200)
    postal_code = models.IntegerField()
    latitude = models.FloatField()
    longitude = models.FloatField()

serializers.py

class CategorySerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Category
        fields = ( 'id', 'name')

class AptSerializer(serializers.HyperlinkedModelSerializer):

    cats = CategorySerializer(many=True, read_only=True)

    class Meta:
        model = Apartment
        fields = ('id_2', 'neighborhood', 'name','district','created','cats','address','postal_code','latitude','longitude')

view.py

class AptViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Apartment.objects.all()
    serializer_class = AptSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_fields = ('id_2', 'neighborhood', 'name', 'district','created','cats','address','postal_code','latitude','longitude')

routers.py

router.register(r'apartments', views.AptViewSet)

As you can see it implements DjangoFilterBackend so now i can filter with urls type

http://localhost:8000/apartments/?district=Eixample

and i get this

 {
    "id_2": 1044121532,
    "neighborhood": "la Nova Esquerra de l'Eixample",
    "name": "Hotel Exe AB Viladomat",
    "district": "Eixample",
    "created": "2001-02-13T00:00:00Z",
    "cats": [
        {
            "id": 1073,
            "name": "Allotjament"
        },
        {
            "id": 1075,
            "name": "Hotels"
        },
        {
            "id": 1076,
            "name": "3 estrelles"
        }
    ],
    "address": "Viladomat 197",
    "postal_code": 8015,
    "latitude": 41.383665702777776,
    "longitude": 2.151834694444444
},

I'd like to make get request like

http://localhost:8000/apartments/?cats_name=Hotels

But it doesn't work, any idea in which will the road from now? Write a custom Filter? write another ViewSet for Category objects?

Thank You

Upvotes: 0

Views: 1094

Answers (2)

Seenu S
Seenu S

Reputation: 3481

The root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset of the complete set of objects.

But here your are passing the query parameters and to filter on whole queryset

views.py

class AptViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Apartment.objects.all()
    serializer_class = AptSerializer

    def get_queryset(self):
        queryset = super(AptViewSet, self).get_queryset()
        cats_name = self.request.query_params.get('cat_name', None)
        if cats_name:
            queryset = queryset.filter(cats__name=cats_name)
        return queryset

If you can follow this post for writing the custom filters How to Pass kwarg to Filter

Upvotes: 3

Erik
Erik

Reputation: 898

Check out this link on query parameter filtering.

You will overriding the get_queryset method in your serializer.

Upvotes: 0

Related Questions