在Django中从URL获取两个字符串变量

9 投票
3 回答
20436 浏览
提问于 2025-04-16 18:32

我在把多个变量传到视图时遇到了一些麻烦。

我的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 个回答

0

name2应该是什么呢?url这个函数需要一个叫name的参数,这个参数是你在反向生成URL时用到的名字,但你不能随便加一些额外的函数。

除此之外,你发送两个元素到视图的语法是正确的。当然,由于你把变量名隐藏了,也没有提供具体的错误信息或错误追踪,我们无法知道到底出了什么问题。

1

其实你不需要给两个名字参数。因为在正则表达式里,你已经有了变量名。真正的问题是,你不能给两个名字参数,所以你可以这样做:

url(r'^rss/(?P<anynumber>[^/]+)/(?P<anystring>[^/]+)/$', 'rss.rssama.views.makerss',name='something'),

编辑:

使用上面的urlConf,你可以创建相应的视图,像这样:

def makerss(request, anynumber, anystring):
28

首先,正则表达式的部分应该看起来像这样:

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的值,或者anystringanynumber都需要有值时,这个函数都可以使用。

我知道这有很多不同的点,所以我会尽量把它们整合在一起,让你看到它是如何工作的。为了有两个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真棒,给它点个赞吧!

Python正则表达式库文档

撰写回答