У меня есть форма django с 2 обязательными полями и некоторыми необязательными полями, которые фильтруют данные, представленные в виде.
В этом представлении используются некоторые параметры GET
, кроме параметров формы фильтра, и я инициализирую свой фильтр как form = MyFilterForm(request.GET or None)
[см. (1) в коде ниже].
Я нахожу, когда мое представление загружается впервые и нет параметров GET
, это прекрасно работает, так как request.GET
неверно, поэтому форма не привязывается (и поэтому мы используем начальные значения для обязательных полей ). Если форма фильтра используется, то request.GET
заполняется параметрами формы и все снова работает хорошо. Однако, если один из моих других GET
параметров (а именно тот, который использовался для сортировки результирующей таблицы данных) будет пропущен без использования формы фильтра, то request.GET
будет верным, но не имеет параметров, соответствующих форме и поэтому форма становится связанной и ошибки как недействительные, потому что мои обязательные поля не получили значения.
Что должно произойти, это то, что таблица данных должна быть отсортирована, и форма должна продолжать использовать исходные («по умолчанию») значения, как при первой загрузке.
Это немного сложно объяснить и может быть понятнее с некоторым кодом ...
Я много гуглил, потому что это похоже на проблему, с которой тоже должны столкнуться другие люди, но не повезло найти что-либо.
Я использую django-tables2 , чтобы представить данные в виде таблицы для пользователя, но этот вопрос больше касается формы, единственное, что вам нужно знать о таблице, это то, что она позволяет Пользователь сортирует данные, представленные в таблице, щелкая заголовок таблицы - это добавляет параметр GET к запросу со столбцом для сортировки по IE ?sort=start_date
.
class MyFilterForm(forms.Form):
date_from = DateTimeField(required=True)
date_to = DateTimeField(required=True)
user = ModelChoiceField(required=False, queryset=User.objects.all())
def __init__(self, *args, **kwargs):
super(MyFilterForm, self).__init__(*args, **kwargs)
# dates in correct timezone and at start/end of day
# initial values set in __init__ so that they aren't fixed at import time
week_start, week_end = get_start_end_week(timezone.now())
self.fields['date_from'].initial = week_start
self.fields['date_to'].initial = week_end
И на мой взгляд
import django-tables2 as tables
@login_required
def view_with_filter_form_and_table(request):
form = MyFilterForm(request.GET or None) # (1) The form gets bound when the table is sorted here as request.GET is truthy
if form.is_bound and form.is_valid():
date_from = self.cleaned_data['date_from']
date_to = self.cleaned_data['date_to']
else:
# use defaults if not bound or not valid
date_from = form.fields['date_from'].initial
date_to = form.fields['date_to'].initial
user = form.cleaned_data.get('user') if form.is_bound else None
query = Action.objects.all()
if date_from:
query = query.filter(date__gte=date_from)
if date_to:
query = query.filter(date__lte=date_to)
if user:
query = query.filter(user=user)
table = MyTable(query)
tables.RequestConfig(request, paginate=False).configure(table)
return render(request, 'my_form_and_table.html', {'form': form, 'table': table})
Что я считал
Проверка того, что все обязательные поля находятся в request.GET
перед привязкой к форме. Помимо того, что он немного пахнет кодом, потому что мне нужно создать экземпляр несвязанной формы, чтобы перебрать все поля и проверить, находятся ли необходимые поля в request.GET
, чтобы даже узнать, должен ли я создавать экземпляр связанной формы. Проблема здесь в том, что если форма редактируется и одно из обязательных полей установлено пустым пользователем, я все еще хочу, чтобы ошибки валидации отображались, иначе This field is required.
.