Выгрузка отфильтрованных данных Django
Всем доброго времени суток. Занимаюсь разработкой приложения на Джанго для изучения веб программирования.
На странице реализована таблица которая выводит значения нужных полей из БД (в том числе связанных моделей), а также передает в шаблон все возможные значения некоторых полей (для возможности выбора поля при фильтрации). Также реализована фильтрация контента по заданным параметрам. К работе вьюхи и фильтра вопросов нет - все работает как и задумано (возможно написано криво, но работает). Но мне нужно реализовать функцию выгрузки предварительно отфильтрованных данных в xls и последующий редирект на эту же страницу с сохранением настроек фильтров.
Ниже куски кода:
def ozp(request):
# получение списков данных для меню выбора -------------------
objectslist = Ozp.objects.all()
dep = Department.objects.all()
ceh_list = []
uchastok_list = []
year_list = []
for i in dep:
if i.ceh in ceh_list:
pass
else:
ceh_list.append(i.ceh)
if i.uchastok in uchastok_list:
pass
else:
uchastok_list.append(i.uchastok)
for i in objectslist:
try:
year = i.zakrytie_date.year
if str(year) in year_list:
pass
else:
year_list.append(str(i.zakrytie_date.year))
except AttributeError:
pass
# --------------------------------------------------------------
# получение введенных в фильр данных --------------------------
if request.GET:
ceh = request.GET['ceh']
uchastok = request.GET['uchastok']
vipolnenie = request.GET['vipolnenie']
na_vipolnenie = request.GET['na_vipolnenie']
year_filter = []
this_month = request.GET['this_month']
# ------------------------------------------------------------------------
# получение списка выбранных годов----------------------------------------
for i in year_list:
q = ''.join(['year_', str(i)])
try:
year_filter.append(request.GET[q])
except KeyError:
pass
# -------------------------------------------------------------------------
# фильтрация по объектам сети----------------------------------------------
filtered_departments = department_filter(ceh, uchastok)[0]
filtered_by_department = " ".join(department_filter(ceh, uchastok)[1])
filtered_objects = Object.objects.filter(uchastok__in=filtered_departments)
filtered_ozp_objects = Ozp.objects.filter(object_name__in=filtered_objects)
# фильтрация по выполнению -----------------------------------------------------
if vipolnenie == '1':
filtered_by_vipolnenie = 'Выполненным'
filtered_ozp_objects = filtered_ozp_objects.filter(is_done=True)
elif vipolnenie == '0':
filtered_by_vipolnenie = 'Невыполненным'
filtered_ozp_objects = filtered_ozp_objects.filter(is_done=False)
else:
filtered_by_vipolnenie = ''
# -----------------------------------------------------------------------------
# фильтрация по поданным на выполннеине ----------------------------------------
if na_vipolnenie == '1':
filtered_by_na_vipolnenie = 'Поданным на устранение'
filtered_podano = Podano_na_vipolnenie.objects.filter(podano=True)
filtered_ozp_objects = filtered_ozp_objects.filter(podano_na_vipolnenie__in=filtered_podano)
elif na_vipolnenie == '0':
filtered_by_na_vipolnenie = 'Не поданным на устранение'
filtered_podano = Podano_na_vipolnenie.objects.filter(podano=False)
filtered_ozp_objects = filtered_ozp_objects.filter(podano_na_vipolnenie__in=filtered_podano)
else:
filtered_by_na_vipolnenie = ''
# -------------------------------------------------------------------
# фильтрация по году-------------------------------------------------
if year_filter != year_list:
filtered_ozp_objects = filtered_ozp_objects.filter(zakrytie_date__year__in=year_filter)
filtered_by_year = 'По следующим годам ' + ' '.join(year_filter)
else:
filtered_by_year = ''
# -------------------------------------------------------------------
# фильтрация по выполнению в течении месяца--------------------------
if this_month == 'this_month':
month = datetime.today() + timedelta(days=30)
filtered_ozp_objects = filtered_ozp_objects.filter(zakrytie_date__lt=month)
filtered_by_month = 'По необходимости выполнения в течении месяца'
else:
filtered_by_month = ''
# -------------------------------------------------------------------
filtered_by = ' '.join([filtered_by_department, filtered_by_vipolnenie, filtered_by_na_vipolnenie,
filtered_by_year, filtered_by_month])
context = {'objectlist': filtered_ozp_objects, 'ceh': ceh_list, 'uchastok': uchastok_list, 'year': year_list,
'filtered_by': filtered_by}
print(filtered_by)
return render(request, "main/templates/ozp.html", context)
else:
filtered_ozp_objects = Ozp.objects.all()
filtered_by = str('')
context = {'objectlist': filtered_ozp_objects, 'ceh': ceh_list, 'uchastok': uchastok_list, 'year': year_list,
'filtered_by': filtered_by}
print(filtered_by)
return render(request, "main/templates/ozp.html", context)
Данная вьюха возвращает в шаблон настройки фильтров, данные для менюшек выбора, строку с указанием по каким параметром выставлены фильтры, и сами данные (объекты). Фильтрацию по полям связанной таблицы вынес в отдельную функцию:
def department_filter(ceh, uchastok):
filtered_by = []
if ceh == 'all' and uchastok == 'all':
filtered_department = Department.objects.all()
elif ceh == 'all' and uchastok != 'all':
filtered_department = Department.objects.filter(uchastok=uchastok)
filtered_by = [uchastok]
elif ceh != 'all' and uchastok == 'all':
filtered_department = Department.objects.filter(ceh=ceh)
filtered_by = [ceh]
else:
filtered_department = Department.objects.filter(Q(ceh=ceh), Q(uchastok=uchastok))
filtered_by = [uchastok, ceh]
return filtered_department, filtered_by
В шаблоне для экспорта реализована отдельная кнопка:
<form action="{% url 'main:export_xls_ozp' filtered_by %}">
<button type="submit">Выгрузить</button>
</form>
Пытаюсь в url передать строку filtered_by но данное решение мне кажется неверным по причине возникновения ошибок в случае отсутствия фильтрации(передачи пустой строки). При этом интуитивно понимаю что мне необходимо в функцию export_xls_ozp передать состояние адресной строки, но как это сделать не знаю. Интернет по запросу мало что выдает.
Кажется разобрался:
<a href="{% url 'main:export_xls_ozp' %}?{{ request.GET.urlencode }}">
<button type="submit">Выгрузить</button>
</a>
Конструкция работает как ссылка. Формирует get запрос к view.export_xls_ozp с параметрами установленного фильтра. В функции export_xls_ozp мы можем легко достать данные параметры при помощи request.GET по необходимому ключу:
def export_xls_ozp(request):
if request.method == 'GET':
ceh = request.GET['ceh']
uchastok = request.GET['uchastok']
vipolnenie = request.GET['vipolnenie']
na_vipolnenie = request.GET['na_vipolnenie']