2010-02-06 11 views
14

Tengo una pregunta bastante simple fijar y unas relacionados vistas genéricas:Siguientes enlaces anteriores de un conjunto de consultas/vistas genéricas

f_detail = { 
     'queryset': Foto.objects.all(), 
     'template_name': 'foto_dettaglio.html', 
     "template_object_name" : "foto", 
     } 

urlpatterns = patterns('', 
# This very include 
(r'^foto/(?P<object_id>\d+)/$', list_detail.object_detail, f_detail,), 
) 

Sólo una plantilla para generar una página de detalles de una foto: lo que no hay vista.


Hay una manera fácil de tener un enlace a anterior | ¿El siguiente elemento en la plantilla sin codificar manualmente una vista?

Somthing como un:

{% if foto.next_item %} 
    <a href="/path/foto/{{ foto.next_item.id_field }}/">Next</a> 
{% endif} 
+0

Mmh ¿qué quieres saber? Sí, es posible que ya hayas proporcionado la solución. Solo tienes que implementar el método 'next_item'. –

+2

http://stackoverflow.com/questions/1931008/is-there-a-clever-way-to-get-the-previous-next-item-using-the-django-orm – shanyu

+0

Vi eso: si lo comprendo bueno, se trata de tener un DateField o DateTimeField en el modelo, que no es mi caso: me gustaría ordenar el resultado de mi queryset por (digamos) el campo id. ¿Hay una forma preconfigurada de atravesar el conjunto de resultados y obtener anterior | los siguientes artículos? ¿O debería diseñar mis propias vistas y codificar una _get_ (next | previous) _item function? – eaman

Respuesta

24
class Foto(model): 
    ... 
    def get_next(self): 
    next = Foto.objects.filter(id__gt=self.id) 
    if next: 
     return next.first() 
    return False 

    def get_prev(self): 
    prev = Foto.objects.filter(id__lt=self.id).order_by('-id') 
    if prev: 
     return prev.first() 
    return False 

se puede ajustar de inmediato a su gusto. Acabo de volver a ver su pregunta ... para que sea más fácil que tener la declaración if, puede hacer que los métodos devuelvan el marcado para el enlace al siguiente/prev si hay uno, de lo contrario, no devuelva nada. luego, simplemente haría foto.get_next, etc. también recuerde que los conjuntos de consulta son flojos, por lo que no obtendrá toneladas de elementos en next/prev.

+0

Gracias, eso es lo que estaba trabajando en este momento: un método personalizado para mi modelo para los enlaces next/prev. Gracias por el ejemplo, estos (id__gt | lt = self.id) se ven mucho mejor de lo que estaba pensando. Muy apreciado. – eaman

+0

'get_prev' y' get_next' devuelven objetos, por lo que tuvieron que usar 'foto.get_next.id' para obtener el pk de next/prev. ¡Gracias! – curtisp

+0

Gracias, por cierto. no es necesario verificar si 'next' y' pref'. 'first()' devuelve 'None' si no se encuentra nada – MartinM

1

Si acepta Model.objects.all() como su queryset, y usted está bien con acaparar elementos next/previous por un campo de fecha (generalmente un campo 'created' con auto_now_add = True dará el mismo orden como identificador de objeto), puede usar get_next_by_foo() and get_previous_by_foo(), donde 'foo' es el campo de fecha.

Para los enlaces siguientes/anteriores de un QuerySet más complicado, usar el Paginator with threshold set to one parece ser la mejor opción.

7

La versión Foto anterior tiene un par de inconvenientes:

  • Haciendo una evaluación booleano como if next: puede ser lento ya que básicamente se carga toda la QuerySet resultado. Use next.exists() o try/except like en mi versión.
  • El resultado get_prev() es incorrecto porque necesita invertir el orden en este caso.

Así que aquí está mi Fwiw versión, que es para una clave principal genérica:

def get_next(self): 
    """ 
    Get the next object by primary key order 
    """ 
    next = self.__class__.objects.filter(pk__gt=self.pk) 
    try: 
     return next[0] 
    except IndexError: 
     return False 

def get_prev(self): 
    """ 
    Get the previous object by primary key order 
    """ 
    prev = self.__class__.objects.filter(pk__lt=self.pk).order_by('-pk') 
    try: 
     return prev[0] 
    except IndexError: 
     return False 
Cuestiones relacionadas