Reputation: 53913
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?
Upvotes: 0
Views: 441
Reputation: 4264
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']
Upvotes: 2