Django 使用reverse()重定向到依赖于查询字符串的URL

发布于 2024-10-08 05:11:51 字数 671 浏览 3 评论 0原文

我正在编写一个 Django 应用程序,其 URL 类似于“http://localhost/entity/id/?overlay=other_id”。其中 id 是特定实体的主键,overlay 是要在显示中覆盖的第二个实体的可选查询参数。用户只能在通过覆盖层查看对象时更新实体。当发布到 /update/id 时,我想重定向回 /entity/id,但我不想在重定向期间丢失我的查询参数,因为视图的更改会令人不快。

例如,我的 url.py 中有以下内容:

...
(r'^update/(?P<id>.+)/(?P<overlay_id>.+)/$', 'update'),
(r'^entity/(?P<id>.+)/$', 'view'),
...

因为更新时需要 override_id,所以它是 URL 的一部分,而不是查询参数。在 django 视图中,我想在成功 POST 后进行重定向,并使用reverse() 来避免在 python 代码中引用 URL。总体思路是:

return HttpResponseRedirect(
  reverse('views.view',
    kwargs={
      'id': id,
    },
  )
)

但是如何反向传递查询参数呢?

谢谢, 克雷格

I'm writing a django application with a URL like 'http://localhost/entity/id/?overlay=other_id'. Where id is the primary key of the particular entity and overlay is an optional query parameter for a second entity to be overlaid in the display. The user can only ever update an entity when viewing objects through an overlay. When POSTing to /update/id, I want to redirect back to /entity/id, but I don't want to lose my query parameter during the redirect, as the change in view would be jarring.

For example, I've got the following in my url.py:

...
(r'^update/(?P<id>.+)/(?P<overlay_id>.+)/

Because overlay_id is required when updating, it's part of the URL, not a query parameter. In the django view I want to redirect after a successful POST and use reverse() to avoid referencing URLs in my python code. The general idea is:

return HttpResponseRedirect(
  reverse('views.view',
    kwargs={
      'id': id,
    },
  )
)

But how do I pass my query parameter though reverse?

Thanks,
Craig

, 'update'), (r'^entity/(?P<id>.+)/

Because overlay_id is required when updating, it's part of the URL, not a query parameter. In the django view I want to redirect after a successful POST and use reverse() to avoid referencing URLs in my python code. The general idea is:


But how do I pass my query parameter though reverse?

Thanks,
Craig

, 'view'), ...

Because overlay_id is required when updating, it's part of the URL, not a query parameter. In the django view I want to redirect after a successful POST and use reverse() to avoid referencing URLs in my python code. The general idea is:

But how do I pass my query parameter though reverse?

Thanks,
Craig

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

黎夕旧梦 2024-10-15 05:11:51

您可以使用 Django QueryDict 对象

from django.http import QueryDict

# from scratch
qdict = QueryDict('',mutable=True)

# starting with our existing query params to pass along
qdict = request.GET.copy()

# put in new values via regular dict
qdict.update({'foo':'bar'})

# put it together
full_url = reversed_url + '?' + qdict.urlencode()

当然,您可以为其编写一个类似于之前答案的便捷方法。

You can use a Django QueryDict object:

from django.http import QueryDict

# from scratch
qdict = QueryDict('',mutable=True)

# starting with our existing query params to pass along
qdict = request.GET.copy()

# put in new values via regular dict
qdict.update({'foo':'bar'})

# put it together
full_url = reversed_url + '?' + qdict.urlencode()

And of course you could write a convenience method for it similar to the previous answer.

许你一世情深 2024-10-15 05:11:51

您不能只检查 overlay_id 并将其添加到您的网址吗?

redirect_url = reverse( ... )
extra_params = '?overlay=%s' % overlay_id if overlay_id else ''
full_redirect_url = '%s%s' % (redirect_url, extra_params)
return HttpResponseRedirect( full_redirect_url )

Can't you just check for an overlay_id and add it to your url?

redirect_url = reverse( ... )
extra_params = '?overlay=%s' % overlay_id if overlay_id else ''
full_redirect_url = '%s%s' % (redirect_url, extra_params)
return HttpResponseRedirect( full_redirect_url )
画中仙 2024-10-15 05:11:51

查询字符串参数应该正确转义,而不仅仅是连接!

通过字符串连接构建带有查询字符串的 url 与通过字符串连接构建 SQL 查询一样糟糕。它很复杂、不优雅,而且对于用户提供的(不受信任的)输入尤其危险。不幸的是,Django 没有提供一种简单的方法来将查询参数传递到 reverse< /a> 函数。

然而,Python 标准 urllib 提供了所需的查询字符串编码功能。

在我的 应用程序 我创建了一个像这样的辅助函数:

def url_with_querystring(path, **kwargs):
    return path + '?' + urllib.urlencode(kwargs)

然后我在视图中调用它,如下所示:

quick_add_order_url = url_with_querystring(reverse(order_add),
    responsible=employee.id, scheduled_for=datetime.date.today(),
    subject='hello world!')
# http://localhost/myapp/order/add/?responsible=5&
#     scheduled_for=2011-03-17&subject=hello+world%21

请注意空格和感叹号等特殊字符的正确编码!

Query string args should be properly escaped and not just concatenated!

Building an url with query string by string concatenation is as bad idea as building SQL queries by string concatenation. It is complicated, unelegant and especially dangerous with a user provided (untrusted) input. Unfortunately Django does not offer an easy possibility to pass query parameters to the reverse function.

Python standard urllib however provides the desired query string encoding functionality.

In my application I've created a helper function like this:

def url_with_querystring(path, **kwargs):
    return path + '?' + urllib.urlencode(kwargs)

Then I call it in the view as follows:

quick_add_order_url = url_with_querystring(reverse(order_add),
    responsible=employee.id, scheduled_for=datetime.date.today(),
    subject='hello world!')
# http://localhost/myapp/order/add/?responsible=5&
#     scheduled_for=2011-03-17&subject=hello+world%21

Please note the proper encoding of special characters like space and exclamation mark!

总攻大人 2024-10-15 05:11:51

您不应该自己生成 url 字符串。给定你的 urls.py 你可以像这样使用反向:

from django.core.urlresolvers import reverse
print reverse('view_function_name', kwargs={"id":"id_value", "overlay_id": "overlay_id_value"})

# or to pass view function arguments as an array:
print reverse('view_function_name', args=("id_value","overlay_id_value",))

如果你使用 命名 url 模式,非常适合将视图函数与 url 标识符断开连接:

# urls.py
...
(r'^update/(?P<id>.+)/(?P<overlay_id>.+)/

使用反向,如下所示:

print reverse("update_foo", kwargs={"id":"id_value", "overlay_id": "overlay_id_value"})
, 'update', name="update_foo"), ...

使用反向,如下所示:

You shouldn't generate the url string yourself. Given your urls.py you can use reverse like so:

from django.core.urlresolvers import reverse
print reverse('view_function_name', kwargs={"id":"id_value", "overlay_id": "overlay_id_value"})

# or to pass view function arguments as an array:
print reverse('view_function_name', args=("id_value","overlay_id_value",))

If you use named url patterns, which are great for disconnecting your view functions from url identifiers:

# urls.py
...
(r'^update/(?P<id>.+)/(?P<overlay_id>.+)/

Use reverse like so:

print reverse("update_foo", kwargs={"id":"id_value", "overlay_id": "overlay_id_value"})
, 'update', name="update_foo"), ...

Use reverse like so:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文