我在urls.py文件一堆网址是有login_required装饰Django的测试,模拟的有效网址请求
# Index Page
url(r'^$', login_required(views.IndexPage.as_view()), name='index'),
# Schedule urls
url(r'^schedules/$', login_required(views.ScheduleListView.as_view()),
name='schedule-list'),
url(r'^schedule/(?P<pk>[\d]+)/$',
login_required(views.ScheduleDetailView.as_view()),
name='schedule-detail'),
url(r'^schedule-freeze/(?P<pk>[\d]+)/$',
login_required(views.freezeSchedule),
name='schedule-freeze'),
url(r'^schedule-create/$', login_required(views.ScheduleCreate.as_view()),
name='schedule-create'),
url(r'^schedule-delete/(?P<pk>[\d]+)$',
login_required(views.ScheduleDelete.as_view()),
name='schedule-delete'),
url(r'^schedule-update/(?P<pk>[\d]+)/$',
login_required(views.ScheduleUpdate.as_view()),
name='schedule-update'),
url(r'^schedule-generate/(?P<pk>[\d]+)/$',
login_required(views.scheduleGenerate), name='schedule-generate'),
# Client urls
url(r'^clients/$', login_required(views.ClientList.as_view()),
name='client-list'),
url(r'^client/(?P<slug>[\w-]+)/$',
login_required(views.ClientDetail.as_view()), name='client-detail'),
url(r'^client-create/$', login_required(views.ClientCreate.as_view()),
name='client-create'),
url(r'^client-delete/(?P<slug>[\w-]+)/$',
login_required(views.ClientDelete.as_view()), name='client-delete'),
url(r'^client-update/(?P<slug>[\w-]+)/$',
login_required(views.ClientUpdate.as_view()), name='client-update'),
# And so on ....
对于每一个管窥我试图写一个测试确保未经授权的用户在尝试访问视图时被重定向到登录页面。如果可能的话,我希望能够在单个代码块中实现这一点,而不是为每个URL编写单个测试。
我已经试过类似如下:
list_urls = [e for e in get_resolver(urls).reverse_dict.keys() if isinstance(e, str)]
for url in list_urls:
# Fetches the urlpath e.g. 'client-list'
namedspaced_url = 'reports:' + url
path = reverse(namedspaced_url)
response = self.client.get(path)
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, reverse('login') + '?next=' + path)
list_urls
返回我的urls.py文件中所有命名的网址即['schedule-create', 'server-detail', 'schedule-list', 'schedule-update', 'index', ....]
名单的问题
这一段代码:reverse(namedspaced_url)
where thi s导致的问题是,每个网址有不同的正则表达式模式,即一些采取slu some一些采取pk的
所以行path = reverse(namedspaced_url)
将适用于简单的URL,如那些指向ListViews但将失败的更复杂的URL,如那些指向DetailViews需要蛞蝓的/ PK的,即path = reverse(namedspaces_url, args=[1945])
是否有可能暂时拒绝/忽略Django的模式匹配/路由强制要求去通过(无论通过参数的个数)
还是我必须使用有效的kwargs/args手动为每个URL编写一个测试来满足regex?
是否有另一种完全不同的方法可以为我的所有login_required()视图编写测试?
更新 使用自省,我想出了以下的怪物,以解决我的问题
def test_page_redirects_for_unauthorised_users(self):
url_dict = get_resolver(urls).reverse_dict
url_list = [e for e in get_resolver(urls).reverse_dict.keys() if
isinstance(e, str)]
for url in url_list:
patterns = url_dict[url][0][0][1]
matches = [1 if e == 'pk' else "slug" if e == 'slug' else None for
e in patterns]
path = reverse('reports:' + url, args=matches)
response = self.client.get(path)
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, reverse('login') + '?next=' + path)
您应该能够内省url解析器中的项目以获取命名参数。然后,您可以以合适的值调用反向,例如, '1945'代表'pk',或'my-slug'代表'slug'。 – Alasdair
你又来了!我玩弄了这个想法,并被劝告反对它,因为这意味着我不得不拿出样本值来匹配我的网址中的每个正则表达式模式(这很快就会变得混乱)。我想知道是否有一个更清洁的解决方案,因为我肯定有人必须在这个问题之前解决一些问题。但是,谢谢你的建议!(如果这是解决此问题的唯一已知方法,那么我想我只需要这样做) –