In Django how can I list a Queryset in one view/template generated by another view?
I'm developing a tracking system that has 2 main datasets Orders
and Shipments
. Focussing on Orders
I want to enable users to enter any combination of field data and then display the resulting list using pagination. To achieve this I have 2 views/templates. One, search_orders
, displays a form that is, essentially, a list of the majority of the dataset fields. The other, list_orders
, displays a list of the selected orders. This all works fine if I just render list_orders
from search_orders
without any pagination but, in order to get pagination I (believe that I) need search_orders
to redirect to list_orders
and, so far, I've been unable to do that.
Search_orders view:
@login_required
def search_orders(request):
if request.method == 'POST' and len(request.POST) > 1:
orders = Order.objects.all()
msg = ''
fields_selected = ''
for fld in request.POST:
if fld == 'orderid' and request.POST.get('orderid'):
msg += f'{fld} - {request.POST.get('orderid')} and '
fields_selected = True
orders = orders.filter(orderid__icontains=request.POST.get('orderid'))
if fld == 'bookingtype' and request.POST.get('bookingtype'):
msg += f'{fld} - {request.POST.get('bookingtype')} and '
fields_selected = True
orders = orders.filter(bookingtype__icontains=request.POST.get('bookingtype'))
if fld == 'shp' and request.POST.get('shp'):
msg += f'{fld} - {request.POST.get('shp')} and '
fields_selected = True
orders = orders.filter(shp__icontains=request.POST.get('shp'))
if fld == 'con' and request.POST.get('con'):
msg += f'{fld} - {request.POST.get('con')} and '
fields_selected = True
orders = orders.filter(con__icontains=request.POST.get('con'))
if fld == 'booked1' and request.POST.get('booked1'):
dt = datetime.datetime.strptime(request.POST.get('booked1'), "%Y-%m-%d").strftime("%d-%b-%y")
msg += f'{fld} - {dt} and '
fields_selected = True
orders = orders.filter(booked__gte=request.POST.get('booked1'))
if fld == 'booked2' and request.POST.get('booked2'):
msg += f'{fld} - {request.POST.get('booked2')} and '
fields_selected = True
orders = orders.filter(booked__lte=request.POST.get('booked2'))
if fld == 'matavail1' and request.POST.get('matavail1'):
msg += f'{fld} - {request.POST.get('matavail1')} and '
fields_selected = True
orders = orders.filter(matavail__gte=request.POST.get('matavail1'))
if fld == 'matavail2' and request.POST.get('matavail2'):
msg += f'{fld} - {request.POST.get('matavail2')} and '
fields_selected = True
orders = orders.filter(matavail__lte=request.POST.get('matavail2'))
if fld == 'reqd1' and request.POST.get('reqd1'):
msg += f'{fld} - {request.POST.get('reqd1')} and '
fields_selected = True
orders = orders.filter(reqd__gte=request.POST.get('reqd1'))
if fld == 'reqd2' and request.POST.get('reqd2'):
msg += f'{fld} - {request.POST.get('reqd2')} anda'
fields_selected = True
orders = orders.filter(reqd__lte=request.POST.get('reqd2'))
if fld == 'origin' and request.POST.get('origin'):
msg += f'{fld} - {request.POST.get('origin')} and '
fields_selected = True
origin = Country.objects.filter(countrycode=request.POST.get('origin'))
orders = orders.filter(origin=origin[0])
if fld == 'destn' and request.POST.get('destn'):
msg += f'{fld} - {request.POST.get('destn')} and '
fields_selected = True
destn = Country.objects.filter(countrycode=request.POST.get('destn'))
orders = orders.filter(destn=destn[0])
if fld == 'shpid' and request.POST.get('shpid'):
msg += f'{fld} - {request.POST.get('shpid')} and '
fields_selected = True
orders = orders.filter(shipment__shpid__icontains=request.POST.get('shpid')).select_related(
'shipment')
if fields_selected:
orders.order_by('-orderid')
#paginator = Paginator(orders, 10) <---- pagination not working
#page_number = request.GET.get('page')
#print(f'Orders selected = {orders}')
#print(f'page_number = {page_number}')
#orders = paginator.page(page_number)
messages.success(request, f'Search criteria: {msg[:-5]}')
else:
orders = Order.objects.none()
messages.success(request, "No field selections entered")
print(f'Orders selected = {orders}')
#return redirect(reverse('tracker:list_orders',kwargs={'action':msg[:-5],'orders':orders}))
#return redirect('tracker:list_orders',kwargs={'action':msg[:-5],'orders':orders})
#return redirect('tracker:list_orders',items)
return render(request, 'tracker/list_orders.html',{'action':msg[:-5],'orders':orders})
else:
#messages.success(request, 'Not in true POST')
return render(request,'tracker/search_orders.html')
List_orders view:
@login_required
def list_orders(request, action):
#orders = Order.objects.all()
if action == 'today':
today = timezone.now().date()
orders = Order.objects.filter(booked=today)
elif action == 'open':
orders = Order.objects.all().exclude(closed=True).order_by('-booked')
paginator = Paginator(orders,16)
page_number = request.GET.get('page',1)
orders = paginator.page(page_number)
return render(request,'tracker/list_orders.html',{'orders':orders,'action':action})
urls.py
app_name = 'tracker'
urlpatterns = [
path("about/", views.about, name="about"),
path("mainmenu/", views.mainmenu, name="mainmenu"),
path("search_orders/", views.search_orders, name="search_orders"),
path("list_orders/<str:action>/", views.list_orders, name="list_orders"),
...
How can I pass the filtered queryset through to list_orders
for paginated display or, alternativery, pass the selected query fields through to list_orders
such that list_orders
can do the filtering?
(In the interests of brevity I've omitted the relevant templates but can add them if desired.)