如何在Django中创建指向来源视图的URL链接?

2 投票
2 回答
2190 浏览
提问于 2025-04-16 03:12

我想要在页面上创建一个返回链接,如果用户是从一个视图过来的话,就链接到那个视图;如果不是从视图过来的话,就链接到一个默认页面(别问……这个需求有点奇怪)。

简单来说,如果用户是从同一个django网站的另一个视图过来的,返回链接就应该指向那个视图。

如果用户是从外部网站过来的,返回链接就应该指向一个默认的视图。

虽然用JavaScript不是最理想的解决方案,但如果没有其他办法,我也愿意考虑。

2 个回答

2

请使用 django.utils.http.is_safe_url() 这个方法。

from django.utils.http import is_safe_url

def my_view(request):
    # ...
    if is_safe_url(url=url, host=request.get_host()):
        back_url = url
    else:
        back_url = default_url
4

使用 django.core.urlresolvers.resolve 可以帮助你判断一个网址是否是内部的 Django 地址。如果不是,它会抛出一个错误 django.core.urlresolvers.Resolver404,如果是的话,它会返回一个匹配对象,你可以根据需要查看这个对象的内容。你可以把 REFERER 环境变量传给这个函数,如果 resolve 抛出错误,就可以用一个默认的网址来替换掉原来的网址。

补充说明:其实不然,resolve 似乎只适用于网址的路径部分。所以你需要先用 urlparse 来解析 REFERER 头,看看它是否是正确的域名。如果是的话,再对解析出来的网址的路径部分使用 resolve 来判断这个网址是否属于你的 Django 网站。

# code not tested, YMMV, etc. 

from urlparse import urlparse

from django.core import urlresolvers

HOME = 'http://my.site.com/'

def generate_back_url(url, default_url=HOME):
    parsed = urlparse(url)
    if parsed.netloc == 'my.site.com':
        try:
            urlresolvers.resolve(parsed.path)
        except urlresolvers.Resolver404:
            back_url = default_url
        else:
            back_url = url
    else:
        back_url = default_url
    return back_url

# ...

def my_view(request):
    # ...
    # truth be told I'm not sure whether the .get() is necessary, sorry.
    back_url = generate_back_url(request.META.get('REFERER', HOME))
    # ...

撰写回答