I am using django-rest-framework
and django-taggit
to add tags to my models.
My models are movie
and book
and both have only a title and tags
from django.db import models
from taggit.managers import TaggableManager
class Movie(models.Model):
title = models.CharField(max_length=255, unique=True)
tags = TaggableManager()
def __str__(self):
return self.title
class Book(models.Model):
title = models.CharField(max_length=255, unique=True)
tags = TaggableManager()
def __str__(self):
return self.title
I serialize the models and build the views
serializers.py
from rest_framework import serializers
from taggit_serializer.serializers import (TagListSerializerField,
TaggitSerializer)
from .models import Movie, Book
class MovieSerializer(TaggitSerializer, serializers.ModelSerializer):
tags = TagListSerializerField()
class Meta:
model = Movie
fields = (
'id',
'title',
'tags',
)
class BookSerializer(TaggitSerializer, serializers.ModelSerializer):
tags = TagListSerializerField()
class Meta:
model = Book
fields = (
'id',
'title',
'tags',
)
views.py
from rest_framework import viewsets
from .models import Movie, Book
from .serializers import MovieSerializer, BookSerializer
class MovieViewSet(viewsets.ModelViewSet):
serializer_class = MovieSerializer
queryset = Movie.objects.all()
class BookViewSet(viewsets.ModelViewSet):
serializer_class = BookSerializer
queryset = Book.objects.all()
Here are also my ulrs.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('apps.movie.urls')),
path('api/', include('apps.book.urls')),
]
from django.urls import path, include
from rest_framework import urlpatterns
from rest_framework.routers import DefaultRouter
from .views import MovieViewSet, BookViewSet
router = DefaultRouter()
router.register('movie', MovieViewSet, basename='movie')
router.register('book', BookViewSet, basename='book')
urlpatterns = [
path('', include(router.urls)),
]
As an example, I report two movies and two books in json format
## movies
{
"id": 1,
"title": "The Lord of the Rings: The Fellowship of the Ring",
"tags": [
"epic",
"fantasy",
"adventure"
]
}
{
"id": 2,
"title": "The Lord of the Rings: The Two Towers",
"tags": [
"epic",
"fantasy",
"adventure"
]
}
## books
{
"id": 1,
"title": "Harry Potter and the Philosopher's Stone",
"tags": [
"fantasy",
"adventure"
]
}
{
"id": 1,
"title": "Crime and Punishment",
"tags": [
"psychological novel",
"philosophical novel"
]
}
I can successfully reach these elements at
http://127.0.0.1:8000/api/movie/<id>/
http://127.0.0.1:8000/api/book/<id>/
What I want is a page for each tag to view both movies and books.
For example to the url
http://127.0.0.1:8000/api/tags/fantasy/
I want
{
"id": 1,
"title": "The Lord of the Rings: The Fellowship of the Ring",
"tags": [
"epic",
"fantasy",
"adventure"
]
}
{
"id": 2,
"title": "The Lord of the Rings: The Two Towers",
"tags": [
"epic",
"fantasy",
"adventure"
]
}
{
"id": 1,
"title": "Harry Potter and the Philosopher's Stone",
"tags": [
"fantasy",
"adventure"
]
}
How can I do this?
So far I get the tags page, with
serializers.py
class TagsSerializer(TaggitSerializer, serializers.ModelSerializer):
class Meta:
model = Tag
fields = (
'__all__'
)
lookup_field = 'slug'
extra_kwargs = {
'url': {'lookup_field': 'slug'}
}
views.py
class TagsViewSet(viewsets.ModelViewSet):
serializer_class = TagsSerializer
queryset = Tag.objects.all()
lookup_field = 'slug'
but this only returns the tag with id, name and slug.
Any help is greatly appreciated!