Django与kwarg重定向

时间:2012-01-19 18:04:58

标签: django redirect

我是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'}'找不到。

我做错了什么?

4 个答案:

答案 0 :(得分:13)

简短回答:您的网址方案中没有“error_message”关键字。

更长的答案:

redirect()函数调用reverse()来构建URL;它将通过返回带有302重定向状态代码的HTTP响应和新URL来将用户的浏览器发送到该URL。您提供给reverse()的任何关键字参数都应该作为URL的一部分结束 - 这就是它们与用户沟通的方式。

在您的情况下,'page_index`的网址只是定义为'^ $' - 这是根网址,在浏览器中看起来像'http://yoursite.com/'。

如果您希望能够发布包含其他信息的重定向,则需要在网址中为其定义地点,或者以不同的方式添加地址。

两个三种方式相当常见:

  1. 使用查询参数 - 这会将消息明确地发送给客户端;如果你不小心,人们可以制作网址,让你的索引页面说出他们想要的东西。

    return redirect(reverse('page-index')+"?error_message=test"))
    
  2. 在会话中存储消息并在下一页加载时将其拉出 - 这需要您配置会话,并跟踪服务器端的所有内容,而不是依赖客户端发送给您返回错误消息:

    def add_page(request):
        request.session['error_message'] = 'test'
        return redirect('page-index')
    
    def page_index(request):
        print request.session.get('error_message','')
    
  3. 使用消息框架 - 这比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 %}
    
  4. 两者所有情况下,您可以从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