Paginate result of a POST form in Django

0

Good, I've been looking for an optimal solution for paging a list of cars resulting from a search through a POST form.

I found the solution by adding that list of cars to request.session but that solution is inefficient and very slow, it takes about 5-8 seconds to save the list in session since there are 80,000 cars in the database.

My view.py

def buscar_coche_avanzado(request):
if request.method == 'POST':
    coches = []
    form = BuscaAvanzadaCocheForm(request.POST)
    if form.is_valid():
        marca = form.cleaned_data['marca']
        precioDesde = form.cleaned_data['precioDesde']
        precioHasta = form.cleaned_data['precioHasta']
        kmsDesde = form.cleaned_data['kmsDesde']
        kmsHasta = form.cleaned_data['kmsHasta']
        anioDesde = form.cleaned_data['anioDesde']
        anioHasta = form.cleaned_data['anioHasta']
        combustible = form.cleaned_data['combustible']
        publicista = form.cleaned_data['publicista']
        provincia =form.cleaned_data['provincia']
        cambio = form.cleaned_data['cambio']
        modelo = form.cleaned_data['modelo']
        marca = form.cleaned_data['marca']

        q=[]
        if marca:
            q.append(Q(marca=marca))
        if precioDesde and not precioHasta:
            q.append(Q(precio__gte=precioDesde))
        if precioHasta and not precioDesde:
            q.append(Q(precio__lte=precioHasta))
        if precioDesde and precioHasta:
            q.append(Q(precio__range=[precioDesde,precioHasta]))
        if kmsDesde and not kmsHasta:
            q.append(Q(kms__gte=kmsDesde))
        if kmsHasta and not kmsDesde:
            q.append(Q(kms__lte=kmsHasta))
        if kmsHasta and kmsDesde:     
            q.append(Q(kms__range=[kmsDesde,kmsHasta]))   
        if anioDesde and not anioHasta:
            q.append(Q(anio__gte=anioDesde))
        if anioHasta and not anioDesde:
            q.append(Q(anio__lte=anioHasta))
        if anioHasta and anioDesde: 
            q.append(Q(anio__range=[anioHasta,anioDesde]))
        if combustible:
            q.append(Q(tipo_combustible=combustible))
        if publicista:
            q.append(Q(tipo_publicista=publicista))
        if provincia: 
            q.append(Q(provincia=provincia))
        if cambio:
            q.append(Q(tipo_cambio=cambio))
        if modelo:
            q.append(Q(modelo__icontains=modelo))

        q_objects = Q() 
        for t in q:
            q_objects &= Q(t) 

        coches = Coche.objects.filter(q_objects) 

        paginator = Paginator(coches, 21) 
        page = request.GET.get('page')

        try:
            coches = paginator.page(page)
        except PageNotAnInteger:
            # Si la página no es un integer devuelve la primera página
            coches = paginator.page(1)
        except EmptyPage:
            # Si la página está fuera de rango devuelve la última página
            coches = paginator.page(paginator.num_pages)  

        return render(request,'lista_coches.html', {'coches':coches, 'BuscaAvanzadaCocheForm':BuscaAvanzadaCocheForm(),'marcas':Marca.objects.all(), 'BuscaCocheForm':BuscaCocheForm()})     

return redirect('lista_coches.html')    

How can I page the cars list? In the template, when I give the following obviously not page because it does not enter by if request.method == 'POST': and to paginate I need the result of the search.

    
asked by Jota 31.12.2016 в 14:30
source

1 answer

0

You can, to keep the form, save the data in the session, but when you save the data I do not mean to save the cars, if not, to save the data of your form in the session, with the aim that without need to do the POST you can retrieve them on the following page:

...
# cambiarías
if request.POST or request.session.get('initial_for_form', None) is not None:
    if request.POST:
        data = request.POST
    else:
        data = request.session.get('initial_for_form')

    form = BuscaAvanzadaCocheForm(data=data)
    if form.is_valid():
        marca = form.cleaned_data['marca']
        precioDesde = form.cleaned_data['precioDesde']
        precioHasta = form.cleaned_data['precioHasta']
        kmsDesde = form.cleaned_data['kmsDesde']
        kmsHasta = form.cleaned_data['kmsHasta']
        anioDesde = form.cleaned_data['anioDesde']
        anioHasta = form.cleaned_data['anioHasta']
        combustible = form.cleaned_data['combustible']
        publicista = form.cleaned_data['publicista']
        provincia =form.cleaned_data['provincia']
        cambio = form.cleaned_data['cambio']
        modelo = form.cleaned_data['modelo']
        marca = form.cleaned_data['marca']

        q = Q()
        if marca:
            q &= (Q(marca=marca))
        if precioDesde and not precioHasta:
            q &= (Q(precio__gte=precioDesde))
        if precioHasta and not precioDesde:
            q &= (Q(precio__lte=precioHasta))
        if precioDesde and precioHasta:
            q &= (Q(precio__range=[precioDesde,precioHasta]))
        if kmsDesde and not kmsHasta:
            q &= (Q(kms__gte=kmsDesde))
        if kmsHasta and not kmsDesde:
            q &= (Q(kms__lte=kmsHasta))
        if kmsHasta and kmsDesde:     
            q &= (Q(kms__range=[kmsDesde,kmsHasta]))   
        if anioDesde and not anioHasta:
            q &= (Q(anio__gte=anioDesde))
        if anioHasta and not anioDesde:
            q &= (Q(anio__lte=anioHasta))
        if anioHasta and anioDesde: 
            q &= (Q(anio__range=[anioHasta,anioDesde]))
        if combustible:
            q &= (Q(tipo_combustible=combustible))
        if publicista:
            q &= Q(tipo_publicista=publicista))
        if provincia: 
            q &= (Q(provincia=provincia))
        if cambio:
            q &= (Q(tipo_cambio=cambio))
        if modelo:
            q &= (Q(modelo__icontains=modelo))

        q_objects = q

        coches = Coche.objects.filter(q_objects) 

        paginator = Paginator(coches, 21) 
        page = request.GET.get('page')

        try:
            coches = paginator.page(page)
        except PageNotAnInteger:
            # Si la página no es un integer devuelve la primera página
            coches = paginator.page(1)
        except EmptyPage:
            # Si la página está fuera de rango devuelve la última página
            coches = paginator.page(paginator.num_pages)

        # escribes la sesion con los datos del formulario
        request.session['initial_for_form'] = form.cleaned_data

        return render(request,'lista_coches.html', {'coches':coches, 'BuscaAvanzadaCocheForm':BuscaAvanzadaCocheForm(),'marcas':Marca.objects.all(), 'BuscaCocheForm':BuscaCocheForm()})     

return redirect('lista_coches.html')

Another way, is to be able to pass all the data from the url and pick it up with the GET, but it is a longer process, and it would be a very long url, although it is the usual way, an example that you can see is in the same admin of django, that when using a filter, change the parameters of the url according to the filter you used

    
answered by 31.12.2016 / 15:06
source