0

So I'm editing an existing codebase using Django Rest Framework, and I added a new field to a model:

class MyModel(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=150, null=True)
    the_new_field = models.IntegerField(null=True, default=None)

I've got a serializer, which is fairly basic:

class MyModelSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = MyModel
        fields = (
            'id',
            'name',
        )

So to the serializer I simply added the new field:

class MyModelSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = MyModel
        fields = (
            'id',
            'name',
            'the_new_field',
        )

I can call the endpoint using name using ?name=awesomename, which actually filters based on awesomename, but when I call the endpoint using ?the_new_field=123456 it simply returns all the records in the database.

What am I missing here? How can I make it filter based on this new field?

kramer65
  • 50,427
  • 120
  • 308
  • 488
  • I've pointed out below a sollution using `django-filter`, but I'm missing your view on this question, can you provide us with it? – Bernardo Duarte Jun 09 '20 at 13:33

1 Answers1

2

You need something like django-filter. It will handle filtering for you, and it's simple to write as a serializer.

Here is how you can integrate with DRF. DRF also recommends using it in their docs. Or follow along:

Install django-filter with pip.

pip install django-filter

Then add django_filters to your INSTALLED_APPS.

INSTALLED_APPS = [
    ...
    'rest_framework',
    'django_filters',
]

If you want to use the django-filter backend by default, add it to the DEFAULT_FILTER_BACKENDS setting.

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
        ...
    ),
}

Or add the filter backend to an individual View or ViewSet.

from django_filters.rest_framework import DjangoFilterBackend

class YourView(generics.ListAPIView):
    ...
    filter_backends = [DjangoFilterBackend]

Then add the filter to your current view as follows:

class MyModelList(generics.ListAPIView):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['name', 'the_new_field']
Bernardo Duarte
  • 4,074
  • 4
  • 19
  • 34
  • 1
    I don't often favor answers pointing at 3rd party libraries- but this is probably good advice. At this point I'm not even sure why drf ships without `django-filter`. – rob Jun 09 '20 at 13:29
  • @rob I'm adding an example, just trying to make it work locally, but pointing out first to speed up the process. I do also favor more examples than links, it's also the SO guideline. – Bernardo Duarte Jun 09 '20 at 13:31