Django:如何获取当前 URL 标记名(用于分页)?
Posted
技术标签:
【中文标题】Django:如何获取当前 URL 标记名(用于分页)?【英文标题】:Django: How can you get the current URL tagname (for pagination)? 【发布时间】:2010-11-16 00:31:01 【问题描述】:我正在尝试使用 URL 中的 page 参数(而不是 GET 参数)进行分页。我还希望我的分页可以跨多个不同模板共享代码。
鉴于此,我认为我需要做这样的事情:
urls.py:
url(r'^alias/page;(?P<page>[0-9]+)/(?P<id>.*)$', alias.get, name="alias"),
模板/别名.html:
<div>...stuff...</div>
% include "paginator.html" %
模板/paginator.html:
% if page_obj.has_previous or page_obj.has_next %
% load filters %
<div class="pagination clear">
% if page_obj.has_previous %
<a href="% url somemagic %" class="prev">‹‹ previous</a>
...
somemagic
是什么?
假设我想保持我的网址不变,除了设置页面page_obj.previous_page_number
【问题讨论】:
您是否已经将 django-pagination 作为替代选项? code.google.com/p/django-pagination 是的,它使用 ?page=4 但我还有其他持久获取参数会妨碍。 您的其他获取参数是“页面”吗? django-pagination 将保持所有其他 get 参数不变。我曾经在每个应用程序上使用它。如果您观看这些截屏视频,您就不会输。 eflorenzano.com/blog/post/first-two-django-screencasts 【参考方案1】:编辑:
您需要 somemagic
是具有当前视图名称的变量。
试试这个:
% with request.path_info|resolve_url_name as current_view %
% url current_view page_obj.previous_page_number object.id %
% endwith %
您可以使用 django-sn-ps 中的一些代码来实现此功能:
-
Variable resolving URL template tag 使 % url % 标记从上下文中解析变量。
Resolve URLs to view name 函数
resolve_to_name(path)
返回path
的视图名称。您只需要创建一个使用此功能的过滤器。
此解决方案不适用于以下网址:
'alias/param1_regexp/param2_regexp/page;(?P<page>[0-9]+)/(?P<id>.*)$'
因为你不知道 param1 和 param2。
可以对上面的 django-sn-ps 进行修改以使这种 url 工作:
第一次 sn-p 修改:
from django.template import defaulttags, VariableDoesNotExist, Variable
class ResolvingURLNode(defaulttags.URLNode):
def render(self, context):
original_view_name = self.view_name
try:
resolved = Variable(self.view_name).resolve(context)
if len(resolved) > 1:
self.view_name = resolved[0]
if resolved[1]:
self.args = [Variable(arg) for arg in resolved[1]]
elif len(resolved) > 0:
self.view_name = resolved[0]
else:
self.view_name = resolved
except VariableDoesNotExist:
pass
ret = super(defaulttags.URLNode, self).render(context)
# restore view_name in case this node is reused (e.g in a loop) in
# which case the variable might resolve to something else in the next iteration)
self.view_name = original_view_name
return ret
defaulttags.URLNode = ResolvingURLNode
第二次 sn-p 修改
from django.core.urlresolvers import RegexURLResolver, RegexURLPattern, Resolver404, get_resolver
__all__ = ('resolve_to_name',)
def _pattern_resolve_to_name(self, path):
match = self.regex.search(path)
if match:
name = ""
if self.name:
name = self.name
elif hasattr(self, '_callback_str'):
name = self._callback_str
else:
name = "%s.%s" % (self.callback.__module__, self.callback.func_name)
if len(match.groups()) > 0:
groups = match.groups()
else:
groups = None
return name, groups
def _resolver_resolve_to_name(self, path):
tried = []
match = self.regex.search(path)
if match:
new_path = path[match.end():]
for pattern in self.url_patterns:
try:
resolved = pattern.resolve_to_name(new_path)
if resolved:
name, groups = resolved
else:
name = None
except Resolver404, e:
tried.extend([(pattern.regex.pattern + ' ' + t) for t in e.args[0 ['tried']])
else:
if name:
return name, groups
tried.append(pattern.regex.pattern)
raise Resolver404, 'tried': tried, 'path': new_path
# here goes monkeypatching
RegexURLPattern.resolve_to_name = _pattern_resolve_to_name
RegexURLResolver.resolve_to_name = _resolver_resolve_to_name
def resolve_to_name(path, urlconf=None):
return get_resolver(urlconf).resolve_to_name(path)
基本上,resolve_to_name 将视图的名称及其参数作为元组返回,new % url myvar %
采用此元组并使用它来反转具有视图名称及其参数的路径。
如果您不喜欢过滤器方法,也可以使用自定义中间件来完成。
上一个答案
您应该检查 django-pagination,它是一个非常好的 django 应用程序,易于使用并完成工作。
使用 django 分页,对可迭代对象进行分页的代码如下:
% load pagination_tags %
% autopaginate myiterable 10 % <!-- 10 elements per page -->
% for item in myiterable %
RENDERING CONTENT
% endfor %
% paginate % <!-- this renders the links to navigate through the pages -->
myiterable 可以是任何可迭代的对象:列表、元组、查询集等
googlecode 上的项目页面: http://code.google.com/p/django-pagination/
【讨论】:
是的,我正在使用它,但它有 ?page= 作为分页方式,这对我不起作用,因为我的网址已经有一些重要的查询参数需要保留。 有趣,为什么实际django中没有这种类型的% url %?对于中间件方法,它的侵入性会更小吗?重写核心 % url % 似乎可能会在未来出现问题。 使用中间件,而不是使用 request.path_info|resolve_to_url 您将在中间件 process_request(request) 方法中调用 resolve_to_url(request.path_info),并将其作为自定义变量添加到请求中。然后它将在您项目的任何模板中可用。如果您有同名的视图和变量,新的 % url % 将失败。您可以通过创建自定义模板标签 % myurl % 并根据需要使用此模板或默认模板来避免这种情况。【参考方案2】:它将类似于以下内容。除了我不知道你所说的 id 是什么意思,所以我只是放了一个通用的对象 id。 url 的语法是 % url view_name param1 param2 ... %
% url alias page_obj.previous_page_number object.id %
根据您的需要更新:
% url alias page_obj.previous_page_number object.id as prev_url %
% include "paginator.html" %
...
% if page_obj.has_previous %
<a href="prev_url" class="prev">‹‹ previous</a>
【讨论】:
但是 pagination.html 将包含在许多其他文件中,用于许多其他 url(具有不同的模板名称)。所以我不能只是把“别名”放在那里。以上是关于Django:如何获取当前 URL 标记名(用于分页)?的主要内容,如果未能解决你的问题,请参考以下文章