Django 按字段而不是主键获取对象
嗨,我对Django和Django Rest框架都是新手。我已经看过教程了。我试图做的(作为一个学习练习)是基于一个字段而不是主键返回一个对象Django 按字段而不是主键获取对象,django,django-rest-framework,Django,Django Rest Framework,嗨,我对Django和Django Rest框架都是新手。我已经看过教程了。我试图做的(作为一个学习练习)是基于一个字段而不是主键返回一个对象 myserver:8000/videos返回所有视频的列表 myserver:8000/videos/1返回主键为1的视频 我想做的是: myserver:8000/videos/:videoname返回视频,其中videoname=videoname 我有以下视频模型: class Videos (models.Model): vide
返回所有视频的列表myserver:8000/videos
返回主键为1的视频myserver:8000/videos/1
返回视频,其中myserver:8000/videos/:videoname
videoname=videoname
class Videos (models.Model):
videoID = models.IntegerField(blank=True, null=True)
videoName = models.CharField(max_length=20)
class Meta:
app_label="quickstart"
我的路由器配置为:
video_detail = views.VideoDetailView.as_view({
'get':'list'
})
urlpatterns = patterns('',
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^videos/(?P<videoName>[^/]+)/$', video_detail)
)
api运行,但当我点击:myserver:8000/videos/SecondVideo/
(其中“SecondVideo”是视频的名称)时,我得到一个404错误
有任何帮助吗?尝试在视图类上设置
查找\u字段
属性。该字段将用于查找单个模型实例。它默认为'pk'
,但您可以将其更改为'videoName'
class VideoDetailView(viewsets.ModelViewSet):
serializer_class = VideosSerializer
lookup_field = 'videoName'
所以我想出来了。发生了什么事
router.register(r'videos', views.VideosViewSet)
正在处理myserver:8000/videos/1,因此我的新url模式url(r'^videos/(?p.+)/$),views.VideoDetailView.as_view())
被注册的路由覆盖。有效的代码是:
urls.py
url(r'^video/(?P<videoName>.+)/$', views.VideoDetailView.as_view())
views.py
class VideoDetailView(generics.ListAPIView):
serializer_class = VideosSerializer
def get_queryset(self):
videoName = self.kwargs['videoName']
return Videos.objects.filter(videoName=videoName)
url.py
url(r“^video/(?P.+)/$”,views.VideoDetailView.as_view())
views.py
类VideoDetailView(generics.ListAPIView):
序列化程序\u类=视频序列化程序
def get_queryset(自我):
videoName=self.kwargs['videoName']
返回Videos.objects.filter(videoName=videoName)
这项针对URL的过滤帮助我将发生的事情拼凑起来。像这样的解决方案怎么样:
def get_object(self):
obj = super(VideoDetailView, self).get_object()
# perform some extra checks on obj, e.g custom permissions
return obj
views.py
class VideoDetailView(generics.RetrieveAPIView):
serializer_class = VideosSerializer
lookup_field = 'videoName'
理由:
您需要一个detailview,因此不需要ListView
而是retrieveapieview
如果需要进一步的操作,只需重写如下方法:
def get_object(self):
obj = super(VideoDetailView, self).get_object()
# perform some extra checks on obj, e.g custom permissions
return obj
功劳
使用lookup\u field定义用于查询表的字段,并使用lookup\u kwargs定义url中的字段
url(r'^videos/(?p[^/]+)/$,视频详细信息)
使用ModelViewSets可以使用@actiondecorator。如果不想更改视图集和序列化程序的完整查找行为,可以定义特定的方法。例如:
class VideoDetailView(viewsets.ModelViewSet):
queryset = Videos.objects.all()
serializer_class = VideosSerializer
@action(detail=True)
def video_name(self, request, pk=None):
queryset = Video.objects.get(videoName=pk) # pk will be the video name
serializer = VideosSerializer(queryset, many=True) # You can specify other serializer if you want here
return Response(serializer.data)
然后,您的url将是:
myserver:8000/视频/第二视频/视频\u名称/
您可以在中阅读更多内容:我继续添加了lookup_字段,但仍然得到了404。还有其他想法吗?或者这不起作用的原因?一旦我找到正确的URL,这对我来说就起作用了。对于刚接触Django的人,您可以使用以下URL查找视频,其中videoName='SecondVideo':
class VideoDetailView(viewsets.ModelViewSet):
queryset = Videos.objects.all()
serializer_class = VideosSerializer
@action(detail=True)
def video_name(self, request, pk=None):
queryset = Video.objects.get(videoName=pk) # pk will be the video name
serializer = VideosSerializer(queryset, many=True) # You can specify other serializer if you want here
return Response(serializer.data)