嗨,我是Django和Django-Rest-Framework的新手。我已经完成了教程。我正在尝试做的(作为学习练习)是返回一个基于主键以外的字段的对象。
myserver:8000/videos
会返回所有视频的列表。myserver:8000/videos/1
返回主键为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)
)
我的观点定义为:
class VideoDetailView(viewsets.ModelViewSet):
serializer_class = VideosSerializer
def get_queryset(self):
videoName = self.kwargs.get(videoName, None)
queryset = super (VideoDetailView,self).get_queryset()
if videoName:
queryset = queryset.filter(videoName=videoName)
return queryset
api运行但是当我点击时:myserver:8000/videos/SecondVideo/
(其中“SecondVideo”是视频的名称)我收到404错误。
任何帮助?
答案 0 :(得分:10)
尝试在视图类上设置lookup_field
属性。这是将用于查找单个模型实例的字段。它默认为'pk'
,但您可以将其更改为'videoName'
。
class VideoDetailView(viewsets.ModelViewSet):
serializer_class = VideosSerializer
lookup_field = 'videoName'
答案 1 :(得分:9)
所以我明白了。
是怎么回事router.register(r'videos', views.VideosViewSet)
正在处理myserver:8000/videos/1
,因此注册路线会覆盖我的新网址格式url(r'^videos/(?P<videoName>.+)/$', 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过滤的documentation page帮助我拼凑了正在发生的事情。
答案 2 :(得分:3)
这样的解决方案怎么样:
views.py
class VideoDetailView(generics.RetrieveAPIView):
serializer_class = VideosSerializer
lookup_field = 'videoName'
推理:
您需要详细视图,因此不需要ListView
但RetriveAPIView
如果需要进行一些操作,只需覆盖get_object
这样的方法:
def get_object(self):
obj = super(VideoDetailView, self).get_object()
# perform some extra checks on obj, e.g custom permissions
return obj
答案 3 :(得分:0)
信用https://www.youtube.com/watch?v=dWZB_F32BDg
使用 lookup_field 定义用于查询表格的字段,并使用 look_up_kwargs 为网址中的字段
<div>
<h2>Title</h2>
<div class="info_row">
<div>Category:</div>
<div>data</div>
</div>
</div>
url(r'^videos/(?P<videoName>[^/]+)/$', video_detail)
答案 4 :(得分:0)
使用 ModelViewSets ,可以使用 @action 装饰器,如果您不想更改视图集和序列化器的完整查找行为,则可以定义特定的方法。例如:
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)
然后,您的网址将是: myserver:8000 / videos / SecondVideo / video_name /
您可以阅读以下内容的更多信息:https://www.django-rest-framework.org/api-guide/viewsets/