Search code examples
pythondjangodjango-rest-frameworkdjango-rest-viewsets

creating custom or modified url using router for retrive method of ModelViewSet


I want to create a custom or modified url using router for ModelViewSet.

Current scenario:

/models.py

class BlogPost(models.Model):
    title = models.CharField(max_length=300)
    description = models.TextField()
    slug = models.SlugField(max_length=300, unique=True)

/serializers.py

class BlogListSerializer(serializers.ModelSerializer):
    class Meta:
        model = BlogPost
        exclude = ('id',)

/views.py

class BlogViewSet(ModelViewSet):
    queryset = BlogPost.objects.all()
    serializer_class = BlogListSerializer

/urls.py

router = DefaultRouter()
router.register(r'blog', BlogViewSet, basename='blog')
urlpatterns = router.urls

Now, I can access the url as below:

list https://localhost:8000/blog

retrieve https://localhost:8000/blog/1

As You can see that the retrieve url can be called using the pk or id. But I have created a model field called slug and its unique. My question is that how do I modify the retrieve url so that I can call the retrieve url using the slug field. For example: https://localhost:8000/blog/test-slug

Note: Why do I want to create a url using slug? Answer: I want to use the urls for sitemap.


Solution

  • If your api needs to return results by querying the slug field (and not the pk field) you could use the lookup_field and lookup_url_kwarg of DRF.

    The pk or id field lookup is the default lookup and mentioned in DRF docs.

    https://www.django-rest-framework.org/api-guide/generic-views/

    views.py

    class BlogViewSet(ModelViewSet):
        queryset = BlogPost.objects.all()
        serializer_class = BlogListSerializer
        lookup_field = 'slug'
        lookup_url_kwarg = 'slug'