Espresso
Espresso

Reputation: 930

Django REST Framework - Query models by field value

I have a Building model for which I have created a Serializer and ModelViewSet. Now I am able to get all Buildings with /api/buildings/ and get a Building object with /api/buildings/3 where 3 is the Building Id.

How do I query for a Building object with a particular attribute value? For example, how do I get the Building object with name == "hospital"? Something like /api/buildings?name=hospital does not work.

views.py

class APIBuildingsViewSet(viewsets.ModelViewSet):
    queryset = Building.objects.all()
    serializer_class = BuildingSerializer

models.py

class Building(models.Model):
    building_id = models.AutoField('ID', auto_created=True, primary_key=True)
    name        = models.CharField('Name', max_length=125, null=True, blank=False, unique=False)
    address     = models.CharField('Address', max_length=256, null=False, blank=False)
    user_id     = models.ForeignKey('accounts.User', on_delete=models.CASCADE, default=1)

    def __str__(self):
        return self.name

serializers.py

class BuildingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Building
        fields = ('building_id', 'name', 'address', 'user_id')

urls.py

router = DefaultRouter()
router.register(r'buildings', views.APIBuildingsViewSet, base_name='buildings')

urlpatterns = [
    url(r'^api/', include(router.urls)),
]

Upvotes: 0

Views: 1439

Answers (2)

Sohail Ahmad
Sohail Ahmad

Reputation: 10177

just change in your view.py file

views.py

from django_filters.rest_framework import DjangoFilterBackend

class APIBuildingsViewSet(viewsets.ModelViewSet):
    queryset = Building.objects.all()
    serializer_class = BuildingSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['name', 'address']

Upvotes: 1

HuLu ViCa
HuLu ViCa

Reputation: 5452

You need to use DjangoFilterBackend in your view, and specify which fields can be used to filter.

First you must install it with pip install django-filter, and add django_filters to settings.py/INSTALLED_APPS, and set your view like this:

...
from django_filters.rest_framework import DjangoFilterBackend

class APIBuildingsViewSet(viewsets.ModelViewSet):
    queryset = Building.objects.all()
    serializer_class = BuildingSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_fields = (building_id, name, address, user_id)

Whit these settings, you would be able to send a post like /api/buildings/?name=hospital (be aware of the slash before the question mark)

Upvotes: 3

Related Questions