I am building an API using Django Rest Framework. I have the /api/localities
endpoint where all of the objects on my database are displayed.
Now I want to create the endpoint for a single page of a particular locality, and I want to make it by slug and not id for example /api/localities/munich.
I am using Class based views and right now I can get the single page by id, for example /api/localities/2, but I want to change that to the slug.
How can I do this?
Here is my code:
models.py
class Localities(models.Model):
id_from_api = models.IntegerField()
city = models.CharField(max_length=255, null=True, blank=True)
slug = models.CharField(max_length=255, null=True, blank=True)
postal_code = models.CharField(max_length=20, null=True, blank=True)
country_code = models.CharField(max_length=10, null=True, blank=True)
lat = models.CharField(max_length=255, null=True, blank=True)
lng = models.CharField(max_length=255, null=True, blank=True)
google_places_id = models.CharField(max_length=255, null=True, blank=True)
search_description = models.CharField(max_length=500, null=True, blank=True)
seo_title = models.CharField(max_length=255, null=True, blank=True)
def __str__(self):
return self.city
serializers.py
from rest_framework import serializers
from .models import Localities
class LocalitiesSerializers(serializers.ModelSerializer):
class Meta:
model = Localities
fields = (
"id",
"id_from_api",
"city",
"slug",
"postal_code",
"country_code",
"lat",
"lng",
"google_places_id",
"search_description",
"seo_title",
)
views.py
from django.shortcuts import render
from django.http import HttpResponse
from wagtail.core.models import Page
from .models import LocalityPage, Localities
from django.core.exceptions import ObjectDoesNotExist
from rest_framework import generics
import json
import requests
from .models import Localities
from .serializers import LocalitiesSerializers
class LocalitiesAll(generics.ListCreateAPIView):
queryset = Localities.objects.all()
serializer_class = LocalitiesSerializers
class LocalitiesDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Localities.objects.all()
serializer_class = LocalitiesSerializers
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('reload', views.convert_json), # app homepage
path("localities/", views.LocalitiesAll.as_view()),
path("localities/<int:pk>/", views.LocalitiesDetail.as_view()),
]
>Solution :
If you want to use slug instead of id then first you need to update your URLs from int:pk to str:slug:
path("localities/<str:slug>/", views.LocalitiesDetail.as_view())
Now update your views.py file class to:
class LocalitiesDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Localities.objects.all()
serializer_class = LocalitiesSerializers
lookup_field = 'slug'
This will help you to reach the goal that you wanted to achieve.