gpt4 book ai didi

python - django - 可选 url 参数的正则表达式

转载 作者:太空狗 更新时间:2023-10-29 21:19:03 24 4
gpt4 key购买 nike

我在 django 中有一个 View 可以接受许多不同的过滤器参数,但它们都是可选的。如果我有 6 个可选过滤器,我真的必须为这 6 个的每个组合编写 url 还是有办法定义 url 的哪些部分是可选的?

给你一个只有 2 个过滤器的例子,我可以拥有所有这些 url 可能性:

/<city>/<state>/
/<city>/<state>/radius/<miles>/
/<city>/<state>/company/<company-name>/
/<city>/<state>/radius/<miles>/company/<company-name>/
/<city>/<state>/company/<company-name>/radius/<miles>/

所有这些 url 都指向同一个 View ,唯一需要的参数是城市和州。使用 6 个过滤器,这变得难以管理。

实现我想要实现的目标的最佳方式是什么?

最佳答案

一种方法是让正则表达式将所有给定的过滤器作为单个字符串读取,然后在 View 中将它们拆分为单独的值。

我想到了以下 URL:

(r'^(?P<city>[^/]+)/(?P<state>[^/]+)(?P<filters>(?:/[^/]+/[^/]+)*)/?$',
'views.my_view'),

匹配所需的城市和州很容易。 filters 部分有点复杂。内部部分 - (?:/[^/]+/[^/]+)* - 匹配以 /name/value 形式给出的过滤器。但是,* 量词(与所有 Python 正则表达式量词一样)仅返回找到的最后一个匹配项 - 因此如果 url 是 /radius/80/company/mycompany/company/mycompany 将被存储。相反,我们告诉它不要捕获单个值(开头的 ?:),并将它放在一个捕获 block 中,该 block 将把所有过滤器值存储为一个字符串。

View 逻辑相当简单。请注意,正则表达式只会匹配过滤器对 - 因此 /company/mycompany/radius/ 不会匹配。这意味着我们可以安全地假设我们有成对的值。我对此进行测试的 View 如下:

def my_view(request, city, state, filters):
# Split into a list ['name', 'value', 'name', 'value']. Note we remove the
# first character of the string as it will be a slash.
split = filters[1:].split('/')

# Map into a dictionary {'name': 'value', 'name': 'value'}.
filters = dict(zip(split[::2], split[1::2]))

# Get the values you want - the second parameter is the default if none was
# given in the URL. Note all entries in the dictionary are strings at this
# point, so you will have to convert to the appropriate types if desired.
radius = filters.get('radius', None)
company = filters.get('company', None)

# Then use the values as desired in your view.
context = {
'city': city,
'state': state,
'radius': radius,
'company': company,
}
return render_to_response('my_view.html', context)

有两点需要注意。首先,它允许未知的过滤器条目进入您的 View 。例如,/fakefilter/somevalue 是有效的。上面的 View 代码忽略了这些,但您可能想向用户报告错误。如果是这样,将获取值的代码更改为

radius = filters.pop('radius', None)
company = filters.pop('company', None)

filters 字典中剩余的任何条目都是您可以提示的未知值。

其次,如果用户重复筛选,将使用最后一个值。例如,/radius/80/radius/50 会将半径设置为 50。如果要检测到这一点,则需要在将值列表转换为字典之前对其进行扫描:

given = set()
for name in split[::2]:
if name in given:
# Repeated entry, complain to user or something.
else:
given.add(name)

关于python - django - 可选 url 参数的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5399035/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com