django - Django Rest Framework - 序列化程序中带有查询参数的 URL
问题描述
我有 aStory
和Post
模型,其中 aPost
属于 a Story
。我想要一个 URL 来获取与给定故事相关联的所有帖子。
我能够覆盖get_queryset
我PostViewSet
的,以便按故事过滤帖子,如http://localhost:8000/posts/?story=1/
. 如果我直接输入 URL,这会很好地工作。现在我想在我的StorySerializer
. 我希望能够获得看起来像这样的故事回复
[
{
"url": "http://localhost:8000/stories/1/",
"title": "Hero's Journey",
"openings": 0,
"date_created": "2020-06-28T16:53:35.150630Z",
"posts": "http://localhost:8000/posts/?story=1/"
},
{
"url": "http://localhost:8000/stories/2/",
"title": "Halo 3",
"openings": 0,
"date_created": "2020-06-28T18:17:12.973586Z",
"posts": "http://localhost:8000/posts/?story=2/"
}
]
这种东西有DRF支持吗?我试图在我的 中使用HyperlinkedIdentityField
with 'post-list'
View StorySerializer
,但我找不到可行的参数组合。我得到的当前异常是
AttributeError: 'Story' object has no attribute 'posts'
序列化器
class StorySerializer(serializers.HyperlinkedModelSerializer):
posts = serializers.HyperlinkedIdentityField(
view_name = 'post-list',
many=True,
lookup_field = 'pk',
lookup_url_kwarg = 'story',
)
class Meta:
model = models.Story
fields = ['url', 'title', 'openings', 'date_created', 'posts']
class PostSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.Post
fields = ['url', 'story', 'user', 'text', 'date_created']
意见
class StoryViewSet(viewsets.ModelViewSet):
queryset = models.Story.objects.all()
serializer_class = serializers.StorySerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = models.Post.objects.all()
serializer_class = serializers.PostSerializer
def get_queryset(self):
queryset = self.queryset
story_id = self.request.query_params.get('story', None)
if story_id is not None:
queryset = queryset.filter(story=story_id)
return queryset
楷模
class Story(models.Model):
title = models.CharField(max_length=100)
date_created = models.DateTimeField(default=timezone.now)
openings = models.PositiveSmallIntegerField(default=0)
participant = models.ManyToManyField(User)
class Post(models.Model):
text = models.CharField(max_length=300)
user = models.ForeignKey(
User,
on_delete=models.PROTECT)
story = models.ForeignKey(
Story,
on_delete=models.PROTECT)
date_created = models.DateTimeField(default=timezone.now)
解决方案
我能够在这里找到一个很好的解决方案,覆盖 get_url 方法以将“pk”值直接映射到“故事”。 https://stackoverflow.com/a/27584761/7308261
from rest_framework.reverse import reverse
import urllib
class StoryPostsHyperlinkedIdentityField(serializers.HyperlinkedIdentityField):
def get_url(self, obj, view_name, request, format):
lookup_field_value = getattr(obj, self.lookup_field, None)
result = '{}?{}'.format(
reverse(view_name, kwargs={}, request=request, format=format),
urllib.parse.urlencode({'story': lookup_field_value})
)
return result
class StorySerializer(serializers.HyperlinkedModelSerializer):
posts = StoryPostsHyperlinkedIdentityField(
view_name='post-list',
)
class Meta:
model = models.Story
fields = ['url', 'title', 'openings', 'date_created', 'posts']
推荐阅读
- python - 不确定有关将多个变量传递给 Python 中的 sql 查询的正确语法
- kubernetes - Kubernetes v1.11.1 从 Kube-api 到节点 kubelet 的连接过多
- python - 在被杀死的线程中无法终止 While 循环
- loops - 如何使用 Brainfuck 中的循环打印从 1 到 10 的数字?甚至可能吗?
- google-apps-script - DriveApp.searchFiles 函数是否对它可以接受的查询数量有限制?
- r - quantregForest x 不包含数据
- c++ - C++ make_shared 调用析构函数两次
- c# - 在 C# 中读取共享点列表
- cell - 如何仅使表格的一列可点击
- c# - Xamarin.IOS 隐藏音量 hud 并按下音量按钮侦听器