django rest框架动态url路由
Posted
技术标签:
【中文标题】django rest框架动态url路由【英文标题】:django rest framework dynamic url route 【发布时间】:2020-01-27 08:20:25 【问题描述】:我目前正在 Django (2.2.5) 和 djangorestframework (3.10.3) 中做一个小项目。我在将视图连接到路由器时遇到问题。我真的很感激能有第二双眼睛帮助我找出问题所在
对于网址我尝试了以下两种:
router = routers.DefaultRouter()
router.register(r'<chatroom>', views.ChatRoomViewSet)
router.register(r'<str:chatroom>', views.ChatRoomViewSet)
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls',namespace='rest_framework')),
path('admin/', admin.site.urls),
]
然后将路由器添加到 urlpatterns。
视图集是:
class ChatRoomViewSet(viewsets.ModelViewSet):
queryset = ChatRoom.objects.all().order_by('name')
serializer_class = ChatRoomSerializer
lookup_field = 'name'
def get_viewset(self, request, name=None):
name = self.kwargs.get('name', None)
queryset = ChatRoom.objects.filter(name=name)
return queryset
序列化器是
class ChatRoomSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ChatRoom
fields = ['url', 'name']
lookup_field = 'name'
型号是:
class ChatRoom(models.Model):
name = models.CharField(max_length=255, default="")
def __str__(self):
return self.name
有什么我明显错过的吗?
【问题讨论】:
你目前的结果是什么?你的期望是什么? 我当前运行 curl 的结果是 curl -H 'Accept: application/json; indent=4' -u user:password 127.0.0.1:8000/first-room Not Found: /first-room [27/Sep/2019 04:21:40] "GET /first-room HTTP/1.1" 404 5038 我保存了几个房间,包括一个以 first-room 为名,我正在将那个房间的详细信息以 json 形式返回 我没有在您的问题上看到您的 urls.py 文件,只是查看路由器,这样可能没有足够的信息让我或其他人回答您的问题。这可能是因为您定义了路由器但未将其添加到您的 urlpattern 中,因此找不到 url127.0.0.1:8000/first-room
如果您在第一个答案下看到我的 cmets,您将看到设置的 url
我更新了 urls 代码片段以包含 urlpatterns
【参考方案1】:
您需要在 urlpatterns 中添加路由器 url
urlpatterns = router.urls
如果已经声明了 url py 然后将该列表与 router.urls 列表连接
urlpatterns += router.urls
【讨论】:
我已经这样做了,正如我在第一个代码框 path('', include(router.urls)) 中提到的,它位于 urlpatterns = [] 数组中【参考方案2】:有一点我想先提一下,让你看看:
似乎您注册了 1 个路径和 1 个视图两次(这不会引起您的问题,只是想提一下)
您将路径参数命名为 chatroom
,但您改用 name
get_viewset
似乎不对,要覆盖默认查询集,您应该改用get_queryset
方法
如果你已经在参数列表中使用了参数名称,像 def get_viewset(self, request, name=None):
这样你就不必再使用 self.kwargs
来获取它,python 已经为你处理了,所以只需使用 @987654327 @函数内部
毕竟代码应该是这样的,
网址
router = routers.DefaultRouter()
router.register(r'(?P<chatroom>.*)', views.ChatRoomViewSet)
视图集
class ChatRoomViewSet(viewsets.ModelViewSet):
queryset = ChatRoom.objects.all().order_by('name')
serializer_class = ChatRoomSerializer
lookup_field = 'pk' # This will use to get the specific ChatRoom, you can remove it also
def get_queryset(self, chatroom=None):
# if you want request, you could use request = self.request
# chatroom is the name you named on your path (<chatroom>)
queryset = ChatRoom.objects.filter(name=chatroom)
return queryset
希望能帮助您解决问题!
【讨论】:
不幸的是,这并没有解决它 - 但谢谢!我忽略了我忘记添加 request 和 chatroom=none :) @ChakoraChandra,刚刚更新了答案。你可以看到我们注册的 url 不同,rest framework 使用正则表达式来匹配 url(它不像path
)。所以试试吧..
我只是得到错误 django.core.exceptions.ImproperlyConfigured: "^(?P^(?P<chatroom>.*)/(?P<user_another_name>[^/.]+)/$
我没有使用您上面粘贴的确切行,django 2.2 改变了 django 处理 url 的方式【参考方案3】:
在您的视图集中将get_viewset
替换为get_queryset
。此外,您可以在视图集中声明 queryset
属性或实现 get_queryset
函数。
【讨论】:
以上是关于django rest框架动态url路由的主要内容,如果未能解决你的问题,请参考以下文章
python-django rest framework框架之路由
如何将命名空间 url 添加到 django-rest-framework 路由器视图集
在 Django Rest Framework 中测试时获取路由器 url 名称