问题描述
我一直在寻找相关主题的答案,但没有一个有效。因此,遵循关于 filtering 的 Django Rest Guid,我想添加通过 url 过滤数据的可能性。
我有我的看法:
class ArtistList(generics.ListAPIView):
serializer_class = ArtistSerializer
def get_queryset(self):
queryset = Artist.objects.all()
name = self.request.query_params.get('name',None)
print(name)
if name is not None:
queryset = queryset.filter(name=name)
return queryset
和我的网址文件:
urlpatterns = [
...
path('artists/<str:name>',ArtistList.as_view(),name='artists'),]
当我提供如下网址时:http://localhost:8000/artists?name=A5
表明该网址不存在。
我还尝试了 http://localhost:8000/artists/A5
,这会导致返回所有艺术家,而不是仅返回 1 个。
我也在指南中的示例中尝试了 re_path('^artists/(?P<name>.+)/$',
,但我仍然遇到错误。这里有什么问题?
我还有第二个问题。使用参数操作 url 的最佳方法是什么?我的意思是我应该声明第一个 url 来返回所有对象,第二个 url 只返回特定对象吗?
解决方法
你混淆了两件事:
-
你有路径,它通常是主机的一部分,在查询字符串之前,查询字符串以
?
开头,所以路径为http://localhost:8000/artists?name=A5
是artists
。 URL 参数放在self.kwargs
中;和 -
你有 querystring 查询字符串是一个键值对集合,从问号开始,这些项存储在
request.query_params
中。
如果您因此想使用 /artists/A5
进行过滤,那么您可以使用:
# http://localhost:8000/artists/A5
class ArtistList(generics.ListAPIView):
serializer_class = ArtistSerializer
def get_queryset(self):
return Artist.objects.filter(name=self.kwargs['name'])
在这种情况下,您总是需要提供一个名称,因为如您所见,不提供名称将返回 HTTP 404 响应。
如果要使用查询字符串,请将路径更改为:
# http://localhost:8000/artists?name=A5
urlpatterns = [
# …,path('artists/',ArtistList.as_view(),name='artists'),]
然后像以前一样使用 self.query_params
。在这种情况下,name=…
部分不需要。
如果您想使用链接 http://localhost:8000/artists?name=A5
,只需重命名您的路径:
urlpatterns = [
...
path('artists',]
如果你想使用 http://localhost:8000/artists/A5
,不要使用 query_params 而是 kwargs :
name = self.kwargs.get('name',None)
在这两种情况下,如果您想返回单个对象,您可能需要查看详细信息视图。 (使用 kwargs 通常与详情视图相关联)