Home > Enterprise >  Django: is it possible to set DateInput widget limits for maximum and minimum dates?
Django: is it possible to set DateInput widget limits for maximum and minimum dates?

Time:04-28

my Date widget in forms.py looks like this:

class DateInput(DateInput):
    input_type = 'date'


class TaskCreateForm(ModelForm):
    class Meta:
        model = TaskModel
        fields = '__all__'
        exclude = ('task_project',)
        widgets = {
            'task_baseline_start': DateInput(),
            'task_baseline_finish': DateInput(),
            'task_scheduled_start': DateInput(),
            'task_scheduled_finish': DateInput(),
            'task_real_start': DateInput(),
            'task_real_finish': DateInput(),
        }

The problem is whenever someone introduces a date too far into the future/past, some other parts of the application get all messed up (like graphs and other stuff).

I've tried the following:

class DateInput(DateInput):
    input_type = 'date'
    attrs = {'min': '2020-01-01'}

But the widget keeps accepting dates before 2020-01-01.

Edit: If I set the attribute on every "DateInput()" instance, the widget will respect the limit, i.e.:

class TaskCreateForm(ModelForm):
    class Meta:
        model = TaskModel
        fields = '__all__'
        exclude = ('task_project',)
        widgets = {
            'task_baseline_start': DateInput(attrs={'min':'2019-01-01'}),
            'task_baseline_finish': DateInput(attrs={'min':'2019-01-01'}),
            'task_scheduled_start': DateInput(attrs={'min':'2019-01-01'}),
            'task_scheduled_finish': DateInput(attrs={'min':'2019-01-01'}),
            'task_real_start': DateInput(attrs={'min':'2019-01-01'}),
            'task_real_finish': DateInput(attrs={'min':'2019-01-01'}),
        }

Now this code hurts my feelings and I feel completely disrespectful for the DRY standards. Is there any better way to set this constraint just once?

Thanks a lot!

CodePudding user response:

The widget does not look at the attrs class attribute. You can add it to the clone, so:

class DateInput(DateInput):
    input_type = 'date'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.attrs.setdefault('min', '2020-01-01')

By using .setdefault(…) [Python-doc], it will not override a different value if you specify one when you construct a DateInput object.

Note that a widget is not validated by Django. You thus still should add a validator in the model (or form field) to prevent against for example forged requests.

  • Related