我有两个具有相同正则表达式的视图,如下所示。这是一个类别和文章视图,它们的入口slu will永远不会相同,所以应该没问题。但目前它并不能很好地运作,因为你们知道类别视图会被触发。
请不要建议使网址结构独特,类别和文章的slu will永远不会相同。它应该尽可能短。
urls.py
urlpatterns = [
url(r'^index', index.Index.as_view(), name='index'),
url(r'^search', search.Index.as_view(), name='search'),
url(r'^(?P<slug>.+)$', category.Index.as_view(), name='category'),
url(r'^(?P<slug>.+)$', article.Index.as_view(), name='article'),
]
如果没有可以找到的类别,我试图从views.category转回urls.py:
views.category.py
class Index(View):
def get(self, request, slug):
category = CategoryModel.objects.get(slug=slug)
if category is None:
return HttpResponseRedirect(reverse('article', args=[slug]))
context = {
'category': category
}
return render(request, 'category/index.html', context)
错误(但有一篇文章有slug'test123'):
NoReverseMatch at /wiki/test123
Reverse for 'article' with arguments '('test123',)' and keyword arguments '{}' not found. 0 pattern(s) tried: []
使用Python 3.6
答案 0 :(得分:0)
为什么不尝试区分这样的网址
urlpatterns = [
url(r'^index', index.Index.as_view(), name='index'),
url(r'^search', search.Index.as_view(), name='search'),
url(r'^category/(?P<slug>.+)$', category.Index.as_view(), name='category'),
url(r'^article/(?P<slug>.+)$', article.Index.as_view(), name='article'),
]
您可以使用相同的正则表达式,而不会使URL不明确。
答案 1 :(得分:0)
您可以移除article.Index
视图,而不是在Category
没有对象时尝试重定向,您可以使用与article.Index
相同的参数调用您在get
中定义的方法{1}}方法接收article.Index
视图。
示例:
urls.py
urlpatterns = [
url(r'^index', index.Index.as_view(), name='index'),
url(r'^search', search.Index.as_view(), name='search'),
url(r'^(?P<slug>.+)$', category.Index.as_view(), name='category'),
# article url removed
]
views.category.py
from path.to.article import Index as ArticleIndexView
class Index(View):
def get(self, request, slug):
category = CategoryModel.objects.get(slug=slug)
if category is None:
# calling article app's Index get method
article_index_view_obj = ArticleIndexView()
return article_index_view_obj.get(request, slug)
context = {
'category': category
}
return render(request, 'category/index.html', context)
如果将article.Index
类视图作为基于函数的视图。
您可以导入from path.to.article import index as article_index
然后,您可以直接调用article_index(request, slug)
。
答案 2 :(得分:0)
这里有几个问题。
(1)您使用reverse
致电args
,但您指定了kwarg
。
if category is None:
return HttpResponseRedirect(reverse('article', args=[slug]))
使用参数'('test123',)'和关键字参数'{}'找不到'article'的反转。
确切地说 - 由于您没有提供关键字参数,因此无法找到匹配的网址格式。这是正确的:
if category is None:
return HttpResponseRedirect(reverse('article', kwargs={'slug':slug}))
(2)你将一次又一次地使用相同的代码 - 一旦你修复了(1)我就会发生这种情况。因为如果reverse
确实反转了网址 - reverse
的结果当然也会匹配category
网址,这意味着它只会再次调用category.Index
视图。 / p>
我认为您的网址设置实际上可以正常工作,因为解析器会按顺序尝试所有网址,直到找到匹配项。我只是不确定您是否可以让视图返回会导致URL解析器启动的内容,并决定采用下一个网址(article
)而不是刚解决的category
。可能不是。
在这种情况下,如果你对重定向很好,你可以定义3个URL模式。 1表示将作为开关操作并分别重定向到CategoryView或ArticleView的视图。
否则,请与Sachin Kukreja在一个视图中处理两者的解决方案一起使用。
答案 3 :(得分:0)
最后我这样做了。实际上我想使用2种不同的视图但我觉得它也很好。有人看到了错误吗?
class Index(View):
def get(self, request, slug):
self.request = request
self.slug = slug
self.item = None
is_article = ArticleModel.objects.filter(slug=self.slug).exists()
if is_article:
self.item = 'article'
return self.article()
is_category = CategoryModel.objects.filter(slug=self.slug).exists()
if is_category:
self.item = 'category'
return self.category()
self.item = None
# 404 here
return HttpResponse(self.item)
def article(self):
article = ArticleModel.objects.get(slug=self.slug)
context = {
'article': article
}
return render(self.request, 'article/index.html', context)
def category(self):
category = CategoryModel.objects.get(slug=self.slug)
context = {
'category': category
}
return render(self.request, 'article/index.html', context)