Filtrar por un queryset con 2 kwargs

publicado por: Anonymous

Tengo una URL en la que paso 2 parámetros:

Edicionlist.hmtl

 <a class="btn btn-primary btn-xs" href="{% url "inscripcion:inscripciones_personas_edicion-list" programa=element.id edicion=element.edicion%}">
 <span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span> Ver inscritos
 </a>

urls.py

urlpatterns = [
url(r'^$', views.InscripcionesIndexView.as_view(), name="index"),

url(r'^inscripcion_personas_edicion/(?P<programa>d+)/(?P<edicion>d+)/$', views.InscripcionesPorEdicionListView.as_view(), name="inscripciones_personas_edicion-list"),
]

Pues bien, ahora quiero filtrar los resultados del modelo por esos 2 campos:

views.py

class InscripcionesPorEdicionListView(ListView):
template_name = "appinscripciones/inscripciones/Inscripcioneslist.html"
model = Inscritos
group_required = ['Básico', 'Administrador']
login_url = "auth-login"

def get_queryset(self):
    qs = super(InscripcionesPorEdicionListView, self).get_queryset()
    return qs.filter(programa__exact=self.kwargs['programa']).filter(edicion__exact=self.kwargs['edicion'])

Pero solo me filtra por el primero, que sería programa. ¿Alguien sabría decirme que estoy haciendo mal en el Queryset?

Muchas gracias.

solución

Bueno, lo único que veo en tu pregunta es lo siguiente:

En tu template:

...
<a class="btn btn-primary btn-xs" href="{% url "inscripcion:inscripciones_personas_edicion-list" programa=element.id edicion=element.edicion%}">
...

Debes cambiar a enteros, por lo que debes poner el id, porque en tus urls.py estas buscando una expresión regular con d+, por lo que tu url solo busca por números, por lo que cámbialo a:

...
<a class="btn btn-primary btn-xs" href="{% url "inscripcion:inscripciones_personas_edicion-list" programa=element.id edicion=element.edicion.id %}">
...

Ahora, en tu método get_queryset() observo cosas innecesarias, entre esas, hacer un filtro por un objeto con el lookup __exact, ya que por defecto ese es el que usa django, por lo que es lo mismo escribir Model.objects.filter(nombre__exact=a) y esto Model.objects.filter(nombre=a). Segundo, si te estan mandando un id en la url, debes buscar y filtrar a partir de ese id.

Por lo que tu método quedaría algo así:

...
def get_queryset(self):
    qs = super(InscripcionesPorEdicionListView, self).get_queryset()
    programa = get_object_or_404(Programa, id=self.kwargs.get('programa', 0))
    edicion = get_object_or_404(Edicion, id=self.kwargs.get('edicion', 0))
    return qs.filter(programa=programa, edicion=edicion)
...

Así seria para asegurar que te el programa y la edición exista, pero para reducir el numero de consultas puedes hacerlo así:

...
def get_queryset(self):
    qs = super(InscripcionesPorEdicionListView, self).get_queryset()
    programa_id = self.kwargs.get('programa', 0)
    edicion_id = self.kwargs.get('edicion', 0)
    return qs.filter(programa_id=programa, edicion_id=edicion)
...

Espero haberte ayudado, cualquier duda, comenta 🙂

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *