Django: How can you get the current URL tag (for pagination)?

I am trying to do pagination with the page parameter in the URL (instead of the GET parameter). I also want my pagination to be shared code on several different templates.

Given this, I think I need to do something like this:

urls.py:

url(r'^alias/page;(?P<page>[0-9]+)/(?P<id>.*)$', alias.get, name="alias"), 

tempaltes / alias.html:

 <div>...stuff...</div> {% include "paginator.html" %} 

templates / 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">&lsaquo;&lsaquo; previous</a> ... 

What is somemagic ?

Suppose I want to keep my url the same, except for setting page_obj.previous_page_number

+4
source share
2 answers

Edit:

You need somemagic be a variable with the name of the current view.

Try the following:

 {% with request.path_info|resolve_url_name as current_view %} {% url current_view page_obj.previous_page_number object.id %} {% endwith %} 

You can get this to work with some code from django-snippets:

  • URL resolver tag variable Makes the tag {% url%} resolved out of context.
  • Allow URL to view name The resolve_to_name(path) function returns the view name for path . You just need to create a filter that uses this function.

This solution will not work with URLs like:

 'alias/param1_regexp/param2_regexp/page;(?P<page>[0-9]+)/(?P<id>.*)$' 

because you have no idea about param1 and param2.

Modification can be done using the django fragments described above to do this type of work:

Changes to the first fragment:

 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 (eg 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 

Changes to the second fragment

 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) 

Basically, send_name returns the view name and its parameters as a tuple, and the new {% url myvar %} takes this tuple and uses it to change the path with the view name and its parameters.

If you do not like the approach to the film, it can also be done using special middleware.


Previous answer

You should check out django-pagination, this is a really nice application for django, just use tu and do the work.

With django pagination, the code for iterating will be as follows:

{% 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 can be any iterable: list, tuple, queryset, etc.

Googlecode project page: http://code.google.com/p/django-pagination/

+2
source

It will be something like the following. Also, I don't know what you mean by identifier, so I just set the identifier of the shared object. Url syntax: {% url view_name param1 param2 ...%}

 {% url alias page_obj.previous_page_number object.id %} 

Updated base according to your needs:

 {% 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">&lsaquo;&lsaquo; previous</a> 
0
source

All Articles