我正在使用Django Rest Framework视图集和路由器设置API端点,我试图让url接受两个值:首先,通过user_id
过滤对象,然后按对象的id过滤。 (在我的例子中,对象来自一个名为Request
的模型。)例如,mysite.com/api/requests/1A/
将为Request
返回所有user 1A
对象,而mysite.com/api/requests/1A/23/
将返回Request
对象与pk=23
为user 1A
。
就在我的urls.py
:
# urls.py
from django.conf.urls import url, include
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register(r'requests/(?P<user_id>.+?)(?=\/)', viewset=views.RequestsByUser, base_name='request')
urlpatterns = [
url(r'^', include(router.urls)),
]
# views.py
class RequestsByUser(viewsets.ModelViewSet):
serializer_class = RequestsSerializer
def get_queryset(self):
u_id = self.kwargs['user_id']
return Request.objects.filter(user_id=u_id)
当url仅通过Request
时,这适用于列出所有user_id
对象。但是当我尝试传递对象的id示例:mysite.com/api/requests/1A/23/
时,rest框架返回一个空结果。
因此,url将通过user_id
正确过滤,但在给定其主键(object_id
)时将无法正确地提供对象的详细视图。 (它看起来像是详细视图的正确页面,除了它缺少对象的数据。)
Django调试说我的URLConf中有以下四个url模式:
^api/ ^ ^test/(?P<user_id>.+?)(?=\/)/$ [name='request-list']
^api/ ^ ^test/(?P<user_id>.+?)(?=\/)\.(?P<format>[a-z0-9]+)/?$ [name='request-list']
^api/ ^ ^test/(?P<user_id>.+?)(?=\/)/(?P<pk>[^/.]+)/$ [name='request-detail']
^api/ ^ ^test/(?P<user_id>.+?)(?=\/)/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='request-detail']
我已经多次阅读了Django Rest Framework文档中的url路由,我觉得我必须遗漏一些东西。我的理解是路由器将根据主键自动为详细视图创建URL路由,看起来它正在URL Conf中这样做。我的正则表达式配置错误,还是别的?
尝试这样的事情:
settings.朋友
INSTALLED_APPS = [
...
'rest_framework',
'django_filters',
...
]
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
}
serialize认识.朋友
import django_filters.rest_framework
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ('id', 'MyField', 'MyFavoriteField','OtherField')
class MyModelListView(generics.ListAPIView):
queryset = MyModel.objects.all()
serializer_class = MyModelSerializer
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)
filter_fields = ('id', 'MyField','MyFavoriteField',)
URLs.朋友:
path('service_name/', MyModelListView.as_view(), name="something_name"),
GET:http://localhost:8070/services/service_name/?id=123&MyField=My%20Field%20Value
更多信息:
https://www.django-rest-framework.org/api-guide/filtering/#filtering