Django ListView personalizando queryset

Esperemos que esto debería ser una simple para ayudarme.

Tengo una página con un menú desplegable que contiene tres elementos:

  Cats Dogs Worms      {% for object in object_list %}  {% endfor %} 
Name Colour
{{ object.name }} {{ object.colour }}

Cuando el usuario selecciona un elemento y pulsa enviar, se les da los resultados en una tabla tal como lo genera el ListView genérico:

 class Browse(generic.ListView): template_name = 'app/browse.html' paginate_by = 25 def get_queryset(self): queryset = Cats.objects.all() if self.request.GET.get("browse"): selection = self.request.GET.get("browse") if selection == "Cats": queryset = Cats.objects.all() elif selection == "Dogs": queryset = Dogs.objects.all() elif selection == "Worms": queryset = Worms.objects.all() else: queryset = Cats.objects.all() return queryset 

Sin embargo, cuando bash pasar una página utilizando los controles de paginación, el conjunto de consultas se restablece en el primer elemento (predeterminado) Cats, porque (creo) los datos del formulario se restablecen.

¿Alguna idea de cómo sortear este problema?

¡Gracias!

PD: Oh, en esa nota, ¿es posible establecer el queryset en none para empezar? ¡Muy agradecido!

ACTUALIZACIÓN: cuando uso la paginación en el conjunto de consultas Cats funciona bien, por lo que el error solo se muestra en los otros dos conjuntos.

Para resolver este problema, acabo de modificar el HTML de paginación, para acomodar tanto la solicitud de obtención del formulario como el número de página en la cadena url, de esta forma:

  

El {{input}} aquí es una cadena que contiene la opción enviada a través del formulario, por ejemplo, ‘Gatos’ o ‘Gusanos’.

Para poder pasar esto a la plantilla, modifiqué el método get_context_data de la vista basada en clase como tal:

 class Browse(generic.ListView): template_name = 'app/browse.html' paginate_by = 25 # Modifying the get_context_data method def get_context_data(self, **kwargs): context = super(Browse, self).get_context_data(**kwargs) q = self.request.GET.get("browse") context['input'] = q return context def get_queryset(self): queryset = Cats.objects.all() if self.request.GET.get("browse"): selection = self.request.GET.get("browse") if selection == "Cats": queryset = Cats.objects.all() elif selection == "Dogs": queryset = Dogs.objects.all() elif selection == "Worms": queryset = Worms.objects.all() else: queryset = Cats.objects.all() return queryset 

Eso fue todo, la cadena url ahora lee algo como:

 /browse/?browse=Cats&page=3 

Así que ahí está, la paginación ahora funciona junto con el método get del formulario.

Puse una etiqueta de plantilla para ayudar a usar las consultas basadas en la respuesta de Sirrah . Ejemplo:

 {{ num }} 

Si la consulta params es un diccionario {'foo': 'bar'} pasado en el contexto, se procesará en algo como esto:

 2 

Sintaxis:

 {% query var_name param=value 'name_only_param' other_param=value|default:'x' another_var %} 

Las variables pueden ser listas, dictados, cadenas o Ninguno (Ninguno se omite).

Código:

 from django import template from django.utils.encoding import force_text from django.template.base import Node, TemplateSyntaxError, kwarg_re, FilterExpression register = template.Library() @register.tag def query(parser, token): bits = token.split_contents() args = [] asvar = None bits = bits[1:] if len(bits) >= 2 and bits[-2] == 'as': asvar = bits[-1] bits = bits[:-2] if len(bits): for bit in bits: match = kwarg_re.match(bit) if not match: raise TemplateSyntaxError("Malformed arguments to url tag") name, value = match.groups() if name: args.append({name: parser.compile_filter(value)}) else: args.append(parser.compile_filter(value)) return QueryNode(args, asvar) class QueryNode(Node): def __init__(self, args, asvar): self.args = args self.asvar = asvar def render(self, context): def join(thing, lst): if isinstance(thing, dict): for k, v in thing.items(): if isinstance(v, FilterExpression): v = force_text(v.resolve(context)) if v is None: continue lst.append('{}={}'.format(k, v)) elif isinstance(thing, list): for it in thing: if isinstance(it, FilterExpression): it = it.resolve(context) join(it, lst) elif isinstance(thing, str): lst.append(thing + '=') elif thing is None: pass else: raise TypeError('Cannot join: %r' % thing) query_lst = [] join(self.args, query_lst) query = '&'.join(query_lst) if self.asvar: context[self.asvar] = query return '' else: return query