2009-08-01 16 views
4

J'essaye de faire la pagination avec le paramètre de page dans l'URL (au lieu du paramètre GET). Je souhaite également que ma pagination soit partagée sur plusieurs modèles différents.Django: Comment pouvez-vous obtenir la balise de l'URL actuelle (pour la pagination)?

Étant donné que, je pense que je dois faire quelque chose comme ceci:

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> 
... 

Qu'est-ce que somemagic?

Supposons que je veux garder mon URL le même, sauf définir la page page_obj.previous_page_number

+0

Avez-vous déjà regardé dans django-pagination comme une option alternative? http://code.google.com/p/django-pagination/ –

+0

Oui, il utilise? Page = 4 mais j'ai d'autres paramètres get persistants qui me gêneront. –

+0

sont vos autres paramètres 'page'? django-pagination gardera tous les autres paramètres intacts. Je l'utilise sur toutes les applications. vous ne pouvez pas perdre si vous regardez ces screencasts. http://www.eflorenzano.com/blog/post/first-two-django-screencasts/ –

Répondre

0

Ce sera quelque chose comme ce qui suit. Sauf que je ne sais pas ce que vous voulez dire par id, donc je viens de mettre un identifiant d'objet générique. La syntaxe URL est {% url nom_vue param1 param2 ...}%

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

base actualisée sur vos besoins:

{% 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

Mais pagination.html sera inclus à partir de nombreux autres fichiers pour beaucoup d'autres URLs (avec des noms de modèles différents). Donc je ne peux pas simplement mettre "alias" dedans. –

2

Edit:

Vous devez somemagic à être une variable avec le nom de la vue actuelle.

Essayez ceci:

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

Vous pouvez obtenir ce travail avec un code de django-extraits:

  1. Variable resolving URL template tag Makes la détermination de la balise {% url%} Les variables de contexte. La fonction resolve_to_name(path) renvoie le nom de la vue path. Vous avez juste besoin de créer un filtre qui utilise cette fonction.

Cette solution ne fonctionnera pas avec urls comme:

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

parce que vous avez pas la moindre idée de param1 et param2.

Une modification peut être fait pour les django-extraits ci-dessus pour faire ce genre d'urls travailler:

modifications du premier extrait de code:

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 

modifications du deuxième extrait de code

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) 

Fondamentalement, resolve_to_name renvoie le nom de la vue d ses paramètres en tant que tuple, et le nouveau{% url myvar %} prend ce tuple et l'utilise pour inverser le chemin avec le nom de la vue et ses paramètres.

Si vous n'aimez pas l'approche du filtre, cela peut également être fait avec un intergiciel personnalisé.


Réponse précédente

Vous devriez vérifier django-pagination, il est une application django vraiment sympa, tu facile utiliser et fait le travail.

Avec le code django paginations pagine un itérables serait:

{% 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 peut être tout ce qui est itérable: liste, tuple, queryset, etc

La page du projet à googlecode: http://code.google.com/p/django-pagination/

+0

oui, je l'utilisais, mais il a? Page = comme la façon de paginer qui ne fonctionne pas pour moi car mes URL ont déjà des paramètres de requête qu'il est important de préserver. –

+0

Intéressant, pourquoi ce type de {% url%} n'est-il pas dans le django actuel? Et pour l'approche middleware, serait-elle moins invasive? La réécriture du noyau {% url%} semble être susceptible de casser quelque chose. –

+0

Avec un middleware, au lieu d'utiliser request.path_info | resolve_to_url, vous appelez resolve_to_url (request.path_info) dans la méthode middleware process_request (request) et l'ajoutez à la requête en tant que variable personnalisée. Ensuite, il serait disponible dans n'importe quel modèle de votre projet. Le nouveau {% url%} échouera si vous avez une vue et une variable avec le même nom. Vous pouvez éviter cela en créant votre template personnalisé {% myurl%} et utilisez celui-ci ou celui par défaut si nécessaire. –