Login

Month / Year SelectDateWidget based on django SelectDateWidget

Author:
pierreben
Posted:
September 7, 2022
Language:
Python
Version:
3.2
Score:
2 (after 2 ratings)

A more simple version of https://djangosnippets.org/snippets/1688/, inheriting from SelectDateWidget, overriding only the necessarily.

Usage example:

In models.py:

from django.db import models
from django.utils.translation import gettext_lazy as _

class MyModel(models.Model):
    start = models.DateField(
        _("Start date"),
    )

    end = models.DateField(
        _("End date"),
    )

    class Meta:
        verbose_name = _("My model")

In forms.py:

from django import forms
from .models import MyModel
from .widgets import MonthYearWidget


class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        exclude = []

        widgets = {
            "start": MonthYearWidget(),
            "end": MonthYearWidget(last_day=True),
        }

kwargs:

  • last_day : if set to True, returns the last day of the month in the generated date.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import calendar
import datetime

from django.forms.widgets import HiddenInput, SelectDateWidget
from django.utils import datetime_safe
from django.utils.formats import get_format


class MonthYearWidget(SelectDateWidget):
    def __init__(self, last_day=False, *args, **kwargs):
        self.last_day = last_day
        return super().__init__(*args, **kwargs)

    def get_context(self, name, value, attrs):
        context = super().get_context(name, value, attrs)
        day_name = self.day_field % name
        day_subwidget = HiddenInput().get_context(
            name=day_name,
            value=1,
            attrs={**context["widget"]["attrs"], "id": "id_%s" % day_name},
        )
        context["widget"]["subwidgets"][0] = day_subwidget["widget"]

        return context

    def value_from_datadict(self, data, files, name):
        value = super().value_from_datadict(data, files, name)
        if self.last_day is True:
            y = data.get(self.year_field % name)
            m = data.get(self.month_field % name)
            if y is not None and m is not None:
                input_format = get_format("DATE_INPUT_FORMATS")[0]
                monthrange = calendar.monthrange(int(y), int(m))
                date_value = datetime.date(int(y), int(m), monthrange[1])
                date_value = datetime_safe.new_date(date_value)
                return date_value.strftime(input_format)
        return value

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 3 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

Please login first before commenting.