在Django中从URL获取两个字符串变量
我在把多个变量传到视图时遇到了一些麻烦。
我的urls.py文件是这样的:
urlpatterns = patterns('',
url(r'^rss/(?P<anything>[^/]+)/$', 'rss.rssama.views.makerss', name='anything'),
url(r'^$', 'rss.rssama.views.home'),
)
views.py文件
def maakrss(request, anything):
现在它可以从www.mydomain.com/rss/[任何内容]/获取信息,并把'任何内容'传给我的视图。不过,我还想再传一个字符串到views.py,比如:
www.mydomain.com/rss/[任意数字]/[任意字符串]/
我试过这样做,但没有成功:
url(r'^rss/(?P<anynumber>[^/]+)/(?P<anystring>[^/]+)/$', 'rss.rssama.views.makerss', name='anynumber', name2='anystring'),
但是这样不行,它给了我这个错误:关键字参数重复(urls.py,第17行)
所以我的问题是:我该怎么做才能从网址中传两个字符串呢?
3 个回答
name2
应该是什么呢?url
这个函数需要一个叫name
的参数,这个参数是你在反向生成URL时用到的名字,但你不能随便加一些额外的函数。
除此之外,你发送两个元素到视图的语法是正确的。当然,由于你把变量名隐藏了,也没有提供具体的错误信息或错误追踪,我们无法知道到底出了什么问题。
其实你不需要给两个名字参数。因为在正则表达式里,你已经有了变量名。真正的问题是,你不能给两个名字参数,所以你可以这样做:
url(r'^rss/(?P<anynumber>[^/]+)/(?P<anystring>[^/]+)/$', 'rss.rssama.views.makerss',name='something'),
编辑:
使用上面的urlConf,你可以创建相应的视图,像这样:
def makerss(request, anynumber, anystring):
首先,正则表达式的部分应该看起来像这样:
r'^/rss/(?P<anynumber>\d+)/(?P<anystring>.+)/$'
在<...>
部分的字符串可以给正则表达式匹配到的内容起个名字。Django会用这个名字把值传递给你的函数。所以你的函数必须有一个同样名字的参数。在这个例子中,Django会把叫anynumber
的值传给你的函数中也叫anynumber
的参数。anystring
也是一样,这样的系统让你不用担心函数参数的顺序。
\d+
会匹配一个或多个数字。如果你只想匹配数字,最好把正则表达式限制为只匹配数字,而不是匹配任何字符然后希望只出现数字。如果你想限制数字的位数,可以用\d{1,4}
来匹配一到四位数字。
接下来的部分(?P<anystring>.+)
会匹配一个由一个或多个任意字符组成的字符串。比如,它会匹配'letters/moreletters'
,包括斜杠。在Python的正则表达式中,有很多“特殊序列”可以帮助你。如果你只想匹配数字、字母和下划线,可以用\w
,像这样(?P<anystring>\w+)
。如果想放宽限制,但忽略空格或其他无关字符,可以用(?P<anystring>[a-zA-Z1-9:;_{}\[\]]
来匹配一大堆字符。确保对任何可能是正则表达式特殊字符的内容进行转义。不过,要谨慎。如果允许的选项太多,谁知道你之后会遇到什么样的bug。
现在说说url
函数的参数名称。这个名称不是它传递给你函数的捕获模式的名称。它是你视图函数调用的一种特定类别的名称,可以在其他地方作为简写使用,比如模板标签{% url view-name arg1 arg2 %}
。所以你已经有的名称“anything”指的是对你的视图函数的调用,传递一个叫“anything”的关键字参数。如果你想传递两个字符串,可以给它起个像“rss-number-string”的名字,以表示你想要的参数,或者一个指代你视图将用这个组合执行的特殊功能的名字。
我经常为同一个函数使用多个名称,关键在于:
def makerss(request, anystring=None, anynumber=None):
通过给参数设置默认值,可以让你以不同的方式使用同一个函数。在这种情况下,当你只想传递anystring
的值,或者anystring
和anynumber
都需要有值时,这个函数都可以使用。
我知道这有很多不同的点,所以我会尽量把它们整合在一起,让你看到它是如何工作的。为了有两个URL,一个捕获字符串并传递,另一个捕获数字、斜杠,然后是字符串,但两个都指向同一个视图函数,你可以这样写:
urlpatterns = patterns('',
url(r'^rss/(?P<anystring>\w+)/$', 'rss.rssama.views.makerss', name='rss-anystring'),
url(r'^rss/(?P<anynumber>\d+)/(?P<anystring>\w+)/$', 'rss.rssama.views.makerss', name='rss-number-string'),
url(r'^$', 'rss.rssama.views.home'),
)
视图函数可能是这样的:
def makerss(request, anystring=None, anynumber=None):
if anystring:
if anynumber:
#Do something with the string and the number
else:
#Do something with just the string
请告诉我这是否有帮助。此外,Django真棒,给它点个赞吧!