Форма 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.

Вернуться на верх