我有多个以前使用id作为查找字段的应用程序接口:
/api/organization/10我有一个使用这些api的前端。
我正在构建一个新的接口,出于某些原因,我想使用一个slug来代替id:
/api/organization/my-orga该API是使用Django Rest框架构建的。除了lookup字段的变化外,api的行为应该保持不变。
有没有办法让我的应用编程接口同时支持slug和pk?这两条路径应该会给出相同的结果:
/api/organization/10
/api/organization/my-orga下面是我的API定义:
# 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发布于 2016-07-19 23:00:19
尝尝这个
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)然后在视图中使用
class Organization(MultipleFieldLookupMixin, viewsets.ModelViewSet):
queryset = OrganisationGroup.objects.all()
serializer_class = OrganizationSerializer
lookup_fields = ('pk', 'another field')发布于 2018-03-31 04:06:19
我通过覆盖retrieve方法并根据任何模式检查pk字段的值,解决了类似的问题。例如,如果它只由数字组成。
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.发布于 2020-06-26 21:42:57
我知道你很久以前就问过这个问题,但这是我从所有答案中得到的完整解决方案,考虑到视图和urls:
把这段代码放到你的views.py中:(在drf中稍微编辑一下)
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添加你想要的字段。如下所示:
class YourDetailView(MultipleFieldLookupMixin, RetrieveUpdateAPIView):
...
lookup_fields = ['pk', 'slug','code']在urls.py中:
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),https://stackoverflow.com/questions/38461366
复制相似问题