Django URL 反转和正则表达式

2 投票
2 回答
3028 浏览
提问于 2025-04-17 00:20

我在我的网址模式中有这个代码 url(r'^(page/(?P<page>\d+)/)?$', 'index', name = 'index_path')

这是我的 views.py 文件

def index(request, page=1):
    posts = Post.objects.filter(published = True)
    paginated_posts = Paginator(posts, 20)

    try:
        target_page = paginated_posts.page(page)
    except EmptyPage:
        return redirect(reverse('index_path'))

    response_dict = {
        'posts': target_page.object_list,
        'page': target_page,
        }

    return render(request, 'posts/index.html', response_dict)`

我用这个来实现简单的分页功能,如果用户什么都不输入,比如直接访问 '/blog/',就会返回第一页;如果用户输入了想要的页码,就返回他们想要的那一页。

这个功能是正常工作的。但是当我想使用 reverse() 函数时,就出现了问题。

当我在交互式命令行中输入:

reverse("index_path")  

我得到了:

 '/blog/'

但是我这样做:

reverse("index_path", args=(1, ))

却出现了一个错误,提示:

NoReverseMatch: Reverse for 'index_path' with arguments '(1, )' and keyword arguments '{}' not found.

附注:在我的主 urls.py 文件中

url(r'^blog/', include('app.posts.urls')),

2 个回答

1

考虑一下这个用于匹配网址的规则表达式。

r'^(blog/(?P<page>\d+)/)?$'

(假设你是想说 blog/ 而不是 page/。)

这个表达式里有两个部分。

  • (blog/(?P<page>\d+)/) 这是一个没有名字的部分,所以我们用 $1 来表示它。
  • (?P<page>\d+) 这是一个有名字的部分,叫做 "page"。

你不想捕捉第一个部分,所以应该用 (?:...) 来替代 (...)

所以,试试用 ^(?:blog/(?P<page>\d+)/)?$ 作为你的匹配规则表达式。然后,试试 reverse('index_path', kwargs={'page': 1})

3

我觉得为了让这个正常工作,你需要有两个网址:

url(r'^page/(?P<page>\d+)$', 'index', name = 'index_path_page'),
url(r'^$', 'index', name = 'index_path'),

然后当你进行反向操作时,你有两个选择:

reverse('index_path_page', args=[1])
# or
reverse('index', args=[1]) # pulls by the name of the view.

第二个选择不太推荐,但在某些地方可能会让逻辑变得更简单。

撰写回答