动态检查是否存在 slug

Dynamically check if a slug exists

在旧版应用程序上,我需要检查 URL 是否存在,如果不存在,则将其重定向到另一个位置。问题是我需要检查 url 是否存在于一组值中,在 urls 文件中,我不清楚如何最好地做到这一点。

例如,项目和城市共享相同的 url 模式。例如/projects/london/projects/my-project-name.

我想先检查 slug 是否匹配城市,如果不匹配,则 return 项目视图(城市无法匹配项目名称)。

我的 url 目前的结构如下:

url(r'^projects/(?P<project-name>[-\w]+)', get_project, name='project-view'),
url(r'^projects/.*', get_city, name='city-view'),

我知道这很乱,而且整体模式很糟糕,但不幸的是,目前无法更改。所以我的目标是弄清楚我是否可以首先检查 project-name 是否可能是一个城市,如果是,则重定向到该视图而不会陷入重定向循环。

我想知道我是否可以做这样的事情:

url(r'^projects/(?P<city>london|paris|new-york)/', get_city, name='city-view'),

其中 london|paris|new-york 是动态生成的

你可以动态生成一个包含所有城市名称的url,但是url会在django第一次访问它时被缓存,所以为了修改url 正则表达式,你必须重新启动 django 进程。如果这适合您的目的,您可以像这样生成 url:

url(r'^projects/(?P<city>{})/$'.format(city_slugs.join('|')),
    get_city, name='city-view')

但是,最好创建一个视图路由方法来实现将请求发送到适当视图的逻辑:

# urls.py
# ...
url(r'^projects/(?P<slug>[-\w]+)/$',
    project_city_router, name='project-city-router'),
# ...

# views.py
def is_a_city(slug):
    # If they're in the database, something like:
    # return City.objects.filter(slug=slug).exists()
    return slug in ['london', 'paris', 'new-york', '...']

def project_city_router(request, slug=None):
    if not slug:
        # /projects/
        return render(request, 'my/template.html', {'foo': 'bar'})
    elif is_a_city(slug):
        # /projects/<city>/
        return get_city(request, city=slug)
    else:
        # /projects/<project-name/
        return get_project(request, project_name=slug)

使用此路由器,如果 slug 参数是一个项目或城市,它 returns 是 get_projectget_city 视图本身的结果。

这还允许根据数据库或文件动态检查您的城市列表。