backend noob here.
I have a question about nested URLs in Django/DRF. I want to nested url structure, for example:
site.com/blog/: shows list of blog.
site.com/blog/blog-name/: which shows single blog with name.
site.com/blog/blog-name/posts: shows the post list of the blog.
site.com/blog/blog-name/posts/some-blog-post: single blog post.
site.com/blog/blog-name/posts/some-blog-post/tags: list of tags.
site.com/blog/blog-name/posts/some-blog-post/tags/1: a tag with id = 1.
I have read this answer but it suggest an additional method in BlogViewset. However I need to nest URLs using two different viewsets. Because as you can see this is just initial fields of an userblog system and I want to be able to manage it without having big files.
I have three models, like this:
class TagModel(models.Model):
tag = models.CharField(max_length=32)
def __str__(self):
return self.tag
class BlogModel(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=1000)
profession = models.CharField(max_length=100)
class Meta:
pass
def __str__(self):
return self.name
class PostModel(models.Model):
title = models.CharField(max_length=120)
content = models.TextField()
tags = models.ManyToManyField(TagModel)
blog = models.ForeignKey(BlogModel, on_delete=models.CASCADE, related_name="posts")
def __str__(self):
return self.title
This is my viewset for Blogs:
from ..models.blog import BlogModel, PostModel
from ..serializers.blog import BlogSerializer
from rest_framework import viewsets
from rest_framework import mixins
from django.shortcuts import render
class BlogViewset(
mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet,
):
queryset = BlogModel.objects.all()
serializer_class = BlogSerializer
# Return all blogs in the database
def list(self, request):
blogs = BlogModel.objects.all()
context = {"blogs": blogs}
return render(request, "blog/home.html", context)
# Return single blog object
def retrieve(self, request, pk):
blog = BlogModel.objects.get(id=pk)
context = {"blog": blog}
return render(request, "blog/blog.html", context)
The viewset for blog post is:
from ..models.blog import BlogModel, PostModel
from rest_framework import mixins
from rest_framework import viewsets
from django.shortcuts import render
class BlogPostViewSet(
mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet,
):
def list(self, request):
posts = PostModel.objects.all()
context = {"posts": posts}
return render(request, "blog/posts.html", context)
def retrieve(self, request, pk):
post = PostModel.objects.get(id=pk)
context = {"post": post}
return render(request, "blog/single.html", context)
And last but not least, I have urls.py like this:
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from blog.viewsets import BlogViewset
from blog.viewsets.post import BlogPostViewSet
blog_router = routers.SimpleRouter()
blog_router.register(r"", BlogViewset, basename="blog")
urlpatterns = [
path("admin/", admin.site.urls),
path("blog/", include(blog_router.urls)),
]
Thank you for your answers.