Django Rest Framework: Get Data by Field

464 views Asked by At

i want to learn django.

My first learning project is a django + rest framework api.

i want to get a destination by its airport code. not by pk / id

currently when i call /api/destination/1 i get the destination with id 1

i want something like /api/destination/PMI or /api/destination/mallorca and as response i only want to get the destination with code PMI or with name mallorca.

is this possible?

my files:

modely.py

class Destination(models.Model):
    name = models.CharField(max_length=50)
    code = models.CharField(max_length=3)
    country = models.CharField(max_length=50)
    image = models.FileField()

serializers.py

class DestinationSerializer(serializers.ModelSerializer):

class Meta:
    model = Destination
    fields = ("id", "name", "code", "country", "image")

urls.py

router = DefaultRouter()
router.register(r'destination', DestinationViewSet)

views.py

class DestinationViewSet(viewsets.ModelViewSet):
    serializer_class = DestinationSerializer
    queryset = Destination.objects.all()
2

There are 2 answers

0
zackcpetersen On BEST ANSWER

I would recommend picking one or the other to have as the identifier. For this example, I'm going to use the airport code.

In urls.py, you'll want to switch from a router to a urlpattern - remember to register this in your project.urls file!

from django.urls import path

urlpatterns = [path('destination/<code>/', DestinationViewSet.as_view())]

In your view, you'll want to switch to just a normal view and call the get() method.

from destinations.api.serializers import DestinationSerializer
from destinations.models import Destination
from rest_framework import views
from rest_framework.response import Response

class DestinationView(views.APIView):
    def get(self, request, code):
        destination = Destination.objects.filter(code=code)
        if destination:
            serializer = DestinationSerializer(destination, many=True)
            return Response(status=200, data=serializer.data)
        return Response(status=400, data={'Destination Not Found'})

Everything else should work the way it is!

0
NoobDjangoist On

Use an action decorator to create a custom get method

@action(detail=False, methods=['GET'], url_path='destination/(?P<pmi>\w{0,500})')
def custom_ge(self, request, pmi):
    #Function implementation in here