views.py
from django.http import Http404, HttpResponse import datetime
def hours_ahead(request, offset):
try:
offset = int(offset)
except ValueError:
raise Http404()
dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
return HttpResponse(html)
urls.py
from django.conf.urls.defaults import *
from mysite.views import hello, current_datetime, hours_ahead
urlpatterns = patterns('',
(r'^hello/$', hello),
(r'^time/$', current_datetime),
(r'^time/plus/(\d{1,2})/$', hours_ahead),
)
它表示参数偏移从匹配的url中提取的值不关心它的名称,但位置很重要。这是它在决定它能做什么之后的第二个参数。 但为什么 ? hours_ahead,只是一个用户定义的方法,而不是类或其他东西。谁赋予它能力,使参数的位置可以这样工作。 所以要明确,我的问题是,“offset = int(offset)”是否有任何意义,为什么偏移量可以在用户设置小时数时从url接收值。
答案 0 :(得分:1)
它的工作方式是Django读取这个url模式r'^time/plus/(\d{1,2})/$'
,提取括号中的参数(在这种情况下为(\d{1,2})
),然后将其作为参数传递给{{ 1}}功能。如果有许多参数,则在url模式中写入它们的顺序也决定了它们被传递到相应视图函数的顺序。您可以在此处详细阅读文档:https://docs.djangoproject.com/en/dev/topics/http/urls/
答案 1 :(得分:0)
它表示从匹配的url中提取的值的参数offset 不关心它的名字,但位置很重要。这是它的第二个 参数站在请求之后决定它能做什么。但为什么呢?
在Python中,您可以将两种参数传递给方法。位置参数和关键字参数。位置参数基于方法签名中的位置,它们的顺序很重要(这就是为什么它们被称为位置,因为它们在方法签名中的位置很重要。)
位置参数必须始终具有值。它们不是可选的。
关键字参数是可以按任何顺序传递的参数 - 只要它们在位置参数之后传入即可。关键字参数可以是可选的。
以下是一个例子:
def foo(a, b, c='Hello', d='World'):
print(a,b,c,d)
a
和b
是位置参数。它们是必需的。您必须传入一个值。 c
和d
是可选的关键字参数,具有默认值。
传递的第一个参数将由a
引用,第二个b
引用。之后,您可以传递d,或c或无:
>>> foo(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() takes at least 2 arguments (1 given)
>>> foo(1,2)
(1, 2, 'Hello', 'World')
>>> foo(1,2,d='Yes')
(1, 2, 'Hello', 'Yes')
>>> foo(1,2,d='Yes',c='No')
(1, 2, 'No', 'Yes')
现在,在django的urls.py中 - 有两种方法可以捕获URL的元素:
^time/plus/(\d+{1,2})/$
- 这是捕获参数并将其作为位置参数传递。捕获的正则表达式的结果将传递给映射请求函数的第二个参数,无论该参数被调用(第一个参数通常称为 request )。
要映射上面的url,你必须有一个view方法,它只需要两个位置参数,但是你可以随意调用它们。请记住, request 是第一个位置参数。现在考虑到这一点,请考虑一下:
def foo(request, a) # You must have two positional arguments
def foo(request, b) # It does not matter what the second argument is called
def foo(request, a, b='world') # You can have any number of
# additional keyword arguments
# but they must be optional (have defaults)
def foo(request, a, b, c='world') # This will fail because you have two
# positional arguments, but only one pattern is
# captured in the URL.
^time/plus/(?P<offset>\d+{1,2})/$
- 此语法(称为命名组)将正则表达式的结果作为关键字参数传递给映射的URL函数。这意味着,2位数的值将作为关键字参数 offset 传递给视图函数。您可以在django documentation。
如果您具有上述命名的组URL模式,那么您的请求方法应具有以下签名:
def hours_ahead(request, offset)
例如,请考虑以下网址格式:
^time/(\d+{1,2})/(\d+{1,2})/(?P<hello>\w+)/$
要匹配此模式,您的视图函数必须具有以下签名:
def foo(request, a, b, hello)
当您收到以下网址time/32/42/world/
时,a
将为32,b
将为42,hello
将具有值世界。
如果您将视图方法中的hello
更改为其他内容,例如def foo(request, a, b, blah)
您的网址将无法映射,因为该模式专门在寻找关键字hello 功能签名。