Форма Django - используйте различные предварительно определенные диапазоны дат для разных вариантов выбора
У меня есть Django форма, где пользователь может выбрать переменную в поле выбора, начальную дату и конечную дату в виджете выбора даты. Для разных переменных возможные начальная и конечная даты различны. Форма работает, но только с одним предопределенным диапазоном дат для всех переменных. Как я могу изменить возможные даты начала и окончания в зависимости от переменной?
from django import forms
from datetime import datetime
Parameter_CHOICES = [
('', 'Wähle ein Umweltvariable'),
('niederschlag', 'Niederschlag [L/m²]'),
('bodentemperatur_5cm', 'Bodentemperatur in 5cm Tiefe [°C]')
]
class DataForm(forms.Form):
parameter = forms.ChoiceField(
widget=forms.Select,
choices=Parameter_CHOICES)
start_date = forms.DateField(label='Beginn:', widget=forms.SelectDateWidget(years=list(range(2007,2023))))
end_date = forms.DateField(label='Ende:', initial=datetime.now, widget=forms.SelectDateWidget(years=list(range(2007,2023))))
Возможно ли это сделать в forms.py или я должен сделать это в javascript/html?
Есть 2 решения, о которых я могу думать:
Виды
Сначала создайте формы, первая из которых позволяет выбрать тип, вторая инициирует форму для опций, которые вы делаете в "get_first_and_second_year":
# forms
class DataForm(forms.Form):
Parameter_CHOICES = [
('', 'Wähle ein Umweltvariable'),
('niederschlag', 'Niederschlag [L/m²]'),
('bodentemperatur_5cm', 'Bodentemperatur in 5cm Tiefe [°C]')
]
parameter = forms.ChoiceField(
widget = forms.Select,
choices = Parameter_CHOICES
)
class DatePickForm(forms.Form):
start_date = forms.DateField(label='Beginn:', widget=forms.SelectDateWidget())
end_date = forms.DateField(label='Ende:', initial=datetime.now, widget=forms.SelectDateWidget())
def __init__(self, *args, **kwargs):
# get kwargs
first_year = kwargs.pop('first_year', None)
second_year = kwargs.pop('second_year', None)
# super
super(DatePickForm, self).__init__(*args, **kwargs)
# initialize form fields
self.fields['start_date'] = forms.DateField(
label='Beginn:',
widget=forms.SelectDateWidget(
years=list(range(first_year,second_year))
)
)
self.fields['end_date'] = forms.DateField(
label='Ende:',
widget=forms.SelectDateWidget(
years=list(range(first_year,second_year))
)
)
Сделайте вызов страницы, используя различные представления:
# call in views
@login_required(login_url="/login/")
def date_form_view(request):
form = DataForm(request.POST or None)
if request.method == 'POST':
#................................................................
# treat form
#................................................................
redirect('date_pick', form_choice=form_choice)
# render with context
context = {'form': form}
render(request, "", context)
def get_first_and_second_year(form_choice):
# return first and second year depending on form choice
match form_choice:
case 'niederschlag':
return first_year, second_year
case 'bodentemperatur_5cm':
return first_year, second_year
case _:
return 0, 0
@login_required(login_url="/login/")
def date_form_view(request, form_choice):
# dont forget to map url to this view with the argument
first_year, second_year = get_first_and_second_year(form_choice)
form = DatePickForm(request.POST or None, first_year=first_year, second_year=second_year)
if request.method == 'POST':
#................................................................
# treat form
#................................................................
start_date = request.POST.get('start_date')
# ...
context = {'form': form}
render(request, "", context)
С ajax (более гладкий интерфейс, сложнее в коде):
Объяснение вызовов Ajax post/get https://www.pluralsight.com/guides/work-with-ajax-django
Передайте в представление json-строку, описывающую различные действия для каждого варианта_формы:
И добавьте html с формой для form_choice.