问题描述
我正在使用 django-rest-framework
和 django-taggit
向我的模型添加标签。
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
我序列化模型并构建视图
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',)
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()
这里也是我的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')),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)),]
举个例子,我以json格式报告两部电影和两本书
## 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","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"
]
}
我可以在
成功到达这些元素http://127.0.0.1:8000/api/movie/<id>/
http://127.0.0.1:8000/api/book/<id>/
以网址为例
http://127.0.0.1:8000/api/tags/fantasy/
我想要
{
"id": 1,"adventure"
]
}
我该怎么做?
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'
但这只会返回带有 id、name 和 slug 的标签。
非常感谢任何帮助!
解决方法
您可以尝试编写继承自 generics.ListView
的新视图,该视图可以返回序列化实例的过滤列表。您需要通过覆盖 get_queryset 方法使用来自 queryset
的标签名称过滤 url
。
urls.py
urlpatterns = [
path('',include(router.urls)),path('tags/<slug:tag_name>/',MoviesByTagSlugViewSet.as_view()),]
views.py
from rest_framework import generics
class MoviesByTagSlugViewSet(generics.ListView):
serializer_class = MovieSerializer
queryset = Movie.objects.all()
def get_queryset(self):
queryset = super().get_queryset()
return queryset.filter(tags__name=self.kwargs['tag_name'])