Django 按字段而不是主键获取对象

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

嗨,我对Django和Django Rest框架都是新手。我已经看过教程了。我试图做的(作为一个学习练习)是基于一个字段而不是主键返回一个对象

  • 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)
)
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)