我已经为ViewSet定义了自定义操作
from rest_framework import viewsets
class UserViewSet(viewsets.ModelViewSet):
@action(methods=['get'], detail=False, permission_classes=[permissions.AllowAny])
def gender(self, request):
....
然后将视图集以常规方式注册到url
from django.conf.urls import url, include
from rest_framework import routers
from api import views
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet, base_name='myuser')
urlpatterns = [
url(r'^', include(router.urls)),
]
URL /api/users/gender/
有效。但是我不知道如何在单元测试中使用reverse
来获得它。 (我当然可以对这个URL进行硬编码,但是从代码中获取它会很好)
根据django documentation,以下代码应正常工作
reverse('admin:app_list', kwargs={'app_label': 'auth'})
# '/admin/auth/'
但是我尝试了以下方法,但它们不起作用
reverse('myuser-list', kwargs={'app_label':'gender'})
# errors out
reverse('myuser-list', args=('gender',))
# '/api/users.gender'
在django-restframework documentation中,有一个名为reverse_action
的函数。但是,我的尝试没有效果
from api.views import UserViewSet
a = UserViewSet()
a.reverse_action('gender') # error out
from django.http import HttpRequest
req = HttpRequest()
req.method = 'GET'
a.reverse_action('gender', request=req) # still error out
反向执行该操作的URL的正确方法是什么?
答案 0 :(得分:4)
答案 1 :(得分:3)
您可以在启动时使用 router
方法打印给定 get_urls()
的所有可逆 url 名称
在将最后一项注册到 router = DefaultRouter()
变量后的 urls.py 中,您可以添加:
#router = routers.DefaultRouter()
#router.register(r'users', UserViewSet)
#...
import pprint
pprint.pprint(router.get_urls())
下次初始化您的应用程序时,它将打印到标准输出
[<RegexURLPattern user-list ^users/$>,
<RegexURLPattern user-list ^users\.(?P<format>[a-z0-9]+)/?$>,
<RegexURLPattern user-detail ^users/(?P<pk>[^/.]+)/$>,
<RegexURLPattern user-detail ^users/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>,
#...
]
其中 'user-list' 和 'user-detail' 是可以赋予 reverse(...)
的名称
答案 2 :(得分:0)
基于DRF Doc。
from rest_framework import routers
router = routers.DefaultRouter()
view = UserViewSet()
view.basename = router.get_default_basename(UserViewSet)
view.request = None
或者您可以根据需要设置请求。
view.request = req
最后,您可以获取并使用反向操作网址。
url = view.reverse_action('gender', args=[])