首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >django rest框架的多个lookup_fields

django rest框架的多个lookup_fields
EN

Stack Overflow用户
提问于 2016-07-19 22:28:25
回答 8查看 17.1K关注 0票数 15

我有多个以前使用id作为查找字段的应用程序接口:

代码语言:javascript
复制
/api/organization/10

我有一个使用这些api的前端。

我正在构建一个新的接口,出于某些原因,我想使用一个slug来代替id:

代码语言:javascript
复制
/api/organization/my-orga

该API是使用Django Rest框架构建的。除了lookup字段的变化外,api的行为应该保持不变。

有没有办法让我的应用编程接口同时支持slugpk?这两条路径应该会给出相同的结果:

代码语言:javascript
复制
/api/organization/10
/api/organization/my-orga

下面是我的API定义:

代码语言:javascript
复制
# urls.py
router = DefaultRouter()
router.register(r'organization', Organization)
urlpatterns = router.urls

#view.py
class Organization(viewsets.ModelViewSet):
    queryset = OrganisationGroup.objects.all()
    serializer_class = OrganizationSerializer

# serializer.py
class OrganizationSerializer(PermissionsSerializer):
    class Meta:
        model = Organization
EN

回答 8

Stack Overflow用户

发布于 2016-07-19 23:00:19

尝尝这个

代码语言:javascript
复制
from django.db.models import Q
import operator
from functools import reduce
from django.shortcuts import get_object_or_404

class MultipleFieldLookupMixin(object):
    def get_object(self):
        queryset = self.get_queryset()             # Get the base queryset
        queryset = self.filter_queryset(queryset)  # Apply any filter backends
        filter = {}
        for field in self.lookup_fields:
            filter[field] = self.kwargs[field]
        q = reduce(operator.or_, (Q(x) for x in filter.items()))
        return get_object_or_404(queryset, q)

然后在视图中使用

代码语言:javascript
复制
class Organization(MultipleFieldLookupMixin, viewsets.ModelViewSet):
    queryset = OrganisationGroup.objects.all()
    serializer_class = OrganizationSerializer
    lookup_fields = ('pk', 'another field')
票数 10
EN

Stack Overflow用户

发布于 2018-03-31 04:06:19

我通过覆盖retrieve方法并根据任何模式检查pk字段的值,解决了类似的问题。例如,如果它只由数字组成。

代码语言:javascript
复制
def retrieve(self, request, *args, **kwargs):
    if kwargs['pk'].isdigit():
        return super(Organization, self).retrieve(request, *args, **kwargs)
    else:
        # get and return object however you want here.
票数 6
EN

Stack Overflow用户

发布于 2020-06-26 21:42:57

我知道你很久以前就问过这个问题,但这是我从所有答案中得到的完整解决方案,考虑到视图和urls:

把这段代码放到你的views.py中:(在drf中稍微编辑一下)

代码语言:javascript
复制
class MultipleFieldLookupMixin(object):

def get_object(self):
    queryset = self.get_queryset()             
    queryset = self.filter_queryset(queryset)  
    filter = {}
    for field in self.lookup_fields:
        if self.kwargs.get(field, None):  
            filter[field] = self.kwargs[field]
    obj = get_object_or_404(queryset, **filter)  # Lookup the object
    self.check_object_permissions(self.request, obj)
    return obj

然后从这个Mixin继承你的视图,并向lookup_fields添加你想要的字段。如下所示:

代码语言:javascript
复制
class YourDetailView(MultipleFieldLookupMixin, RetrieveUpdateAPIView):
    ...
    lookup_fields = ['pk', 'slug','code']

在urls.py中:

代码语言:javascript
复制
re_path(r'^organization/(?P<pk>[0-9]+)/$',
        YourDetailView),
re_path(r'^organization/(?P<slug>[-a-zA-Z0-9_]+)/$',
        YourDetailView),
re_path(r'^organization/sth_else/(?P<code>[0-9]+)/$',
        YourDetailView),
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38461366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档