我是python和django的新手,我对重定向功能有疑问。
这是我的views.py文件的缩减版。
def page_index(request, error_message=''):
print error_message
def add_page(request):
return redirect('page_index') # this work fine
return redirect('page_index', error_message='test') # this does not work
这是我的urls.py的简短版本
urlpatterns = patterns(
'x.views',
url(r'^$', 'page_index', {'error_message': 't'}, name='page_index'),
url(r'^add/$', 'add_page', name='add_page'),
)
当我尝试重定向到没有关键字参数的page_index时,一切正常,但是当我使用kwag时,我收到以下错误消息:
/ pages / add /
中的NoReverseMatch反向'page_index',参数'()'和关键字参数'{'error_message':'test'}'找不到。
我做错了什么?
答案 0 :(得分:13)
简短回答:您的网址方案中没有“error_message”关键字。
更长的答案:
redirect()函数调用reverse()来构建URL;它将通过返回带有302重定向状态代码的HTTP响应和新URL来将用户的浏览器发送到该URL。您提供给reverse()的任何关键字参数都应该作为URL的一部分结束 - 这就是它们与用户沟通的方式。
在您的情况下,'page_index`的网址只是定义为'^ $' - 这是根网址,在浏览器中看起来像'http://yoursite.com/'。
如果您希望能够发布包含其他信息的重定向,则需要在网址中为其定义地点,或者以不同的方式添加地址。
两个三种方式相当常见:
使用查询参数 - 这会将消息明确地发送给客户端;如果你不小心,人们可以制作网址,让你的索引页面说出他们想要的东西。
return redirect(reverse('page-index')+"?error_message=test"))
在会话中存储消息并在下一页加载时将其拉出 - 这需要您配置会话,并跟踪服务器端的所有内容,而不是依赖客户端发送给您返回错误消息:
def add_page(request):
request.session['error_message'] = 'test'
return redirect('page-index')
def page_index(request):
print request.session.get('error_message','')
使用消息框架 - 这比ad-hoc会话属性更受欢迎,只要您在同一页面上不需要太多“类型”消息即可。但是,如果你所拥有的只是模板中的空格,那么这很容易:
from django.contrib.messages import error
def add_page(request):
error(request, 'test')
return redirect('page-index')
然后在你的基本模板中,在某个地方有一个这样的块(可能比这更复杂;甚至是样式):
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
在两者所有情况下,您可以从urls.py中删除参数 - 消息本身不会成为URL的路径组件的一部分。
urlpatterns = patterns(
'x.views',
url(r'^$', 'page_index', name='page_index'),
url(r'^add/$', 'add_page', name='add_page'),
)
答案 1 :(得分:2)
您可以为每条错误消息创建一个命名的url模式,并将其传递给args dict,如下所示:
url(r'^$', 'page_index', {'error_message': 'test'}, name='test_page_index'),
或者如果您愿意将错误消息放在实际网址中,您可以选择:
url(r'(?P"<"error_message">"\w+)/^$', 'page_index', name='page_index'),
(请删除“&lt;”和“&gt;”周围的“”,不得不将它们放在方括号中,否则它们将被排除在答案之外,我想所有看起来像html标签的内容都会被过滤掉)< / p>
并在视图中:
return redirect(reverse('page_index', args=['test']))
答案 2 :(得分:0)
redirect
必须重定向到实际网址(这是HTTP重定向,而不仅仅是Python调用)。
你的url conf中没有'error_message'段,即使你已经设置好了,默认情况下调用视图 function 并将error_message作为kwarg调用。
由于这是您的索引页面,并且您可能不希望在网址中添加额外的路径段,因此您可以使用GET变量来破解它。例如
def page_index(request):
if 'error_message' in request.GET:
print request.GET['error_message']
from django.core.urlresolvers import reverse
def add_page(request):
return redirect('%s?error_message=test' % reverse('page_index'))
urlpatterns = patterns(
'x.views',
url(r'^$', 'page_index', name='page_index'),
url(r'^add/$', 'add_page', name='add_page'),
)
<强>更新强>
当我走回家时想到这一点,虽然你的问题是关于重定向和kwargs等,可以说这里更好的选择是使用Django的messages framework并让error_message
完全离开你的视图kwargs ,GET变量等。
例如
from django.contrib import messages
def add_page(request):
messages.add_message(request, messages.ERROR, 'test')
return redirect('page_index')
这也避免了人们使用自己编写的错误消息来制作网址,这可能会带来安全风险。
答案 3 :(得分:0)
您可以使用django消息。例如:
from django.contrib.auth import messages
messages.info(request, False, "success")
return redirect("app:url")
然后在html中,你可以使用自定义过滤器来获取基于密钥的消息值,因为消息只不过是字典。
{% with messages_dict|get_value_from_dict:'success' as success %}
{% if sucess %}
$('#notification_modal').modal('open');
{% endif %}
{% endwith %}
自定义过滤器,可以包含在app
下的templatetags文件夹中from django import template
register = template.Library()
@register.filter('get_value_from_dict')
def get_value_from_dict(dict_data, key):
"""
usage example {{ your_dict|get_value_from_dict:your_key }}
"""
if key:
return dict_data.get(key)
else:
return None