iFunction
iFunction

Reputation: 1268

Django UpdateForm DateInput widget not showing date

I'm using the DateInput widget to provide a datepicker when a date field is input. However on my update form, the form pulls all the data for that recordd, except the date, which shows up as:

dd/mm/yyy

How do I get the already input date to show" models.py

class Project(models.Model):
    '''
    Main Project, serves the default Projects Portal window.
    '''
    published = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    area = models.ForeignKey(
        Area,
        related_name="project",
        on_delete=models.PROTECT
        )
    title = models.CharField(max_length=128, unique=True)
    slug = models.SlugField(max_length=64)
    summary = models.CharField(max_length=256)
    others = models.CharField(max_length=128, blank=True)
    staff_trials = models.DateField(null=True, blank=True)
    deadline = models.DateField()
    slip = models.BooleanField(default=False)

    class Meta:
        ordering = ["-slip", "deadline"]

    def __str__(self):
        return self.title

forms.py

class DateInput(forms.DateInput):
    input_type = 'date'

class ProjectModelForm(forms.ModelForm):
    """
    Form used for creating and editing projects. Authenticated User
    required to be signed in.
    """
    title = forms.CharField(widget=forms.Textarea)
    summary = forms.CharField(widget=forms.Textarea)

    class Meta:
        model = Project
        fields = (
            'title',
            'summary',
            'others',
            'staff_trials',
            'deadline',
            'area',
        )
        widgets = {
            'staff_trials': DateInput(),
            'deadline': DateInput(),
        }

veiws.py

class ProjectEditView(UpdateView):
    template_name = 'project_portal/project_detail.html'
    form_class = ProjectModelForm
    queryset = Project.objects.all()

    def form_valid(self, form):
        user = self.request.user
        form.instance.user = user
        print(form.cleaned_data)
        return super().form_valid(form)

    def get_object(self):
        slug_ = self.kwargs.get("slug")
        return get_object_or_404(Project, slug=slug_)

Upvotes: 0

Views: 3269

Answers (1)

KrazyMax
KrazyMax

Reputation: 959

You should not define again title and summary. If you want to have a text area widget, just specify that in the Meta part of your form, it's cleaner. I do not think it is useful to override the default forms.DateInput in your case.

class ProjectModelForm(forms.ModelForm):
    class Meta:
        model = Project
        fields = (
            'title',
            'summary',
            'others',
            'staff_trials',
            'deadline',
            'area',
        )
        widgets = {
            'title': forms.Textarea(),
            'summary': forms.Textarea(),
            'staff_trials': forms.DateInput(),
            'deadline': forms.DateInput(),
        }

Finally, are you sure the good object is being used for your update view? Are the fields title, summary etc the ones expected?


EDIT : another solution, with django-tempus-dominus package, really useful and with a nice widget.

Install the widget

pip install django-tempus-dominus

Then, add the application tempus_dominus to your INSTALLED_APPS setting.

Use the widget in your form

# forms.py

from tempus_dominus.widgets import DatePicker
class ProjectModelForm(forms.ModelForm):
    class Meta:
        model = Project
        fields = [
            'title',
            'summary',
            'others',
            'staff_trials',
            'deadline',
            'area',
        ]
        widgets = {
            'deadline': DatePicker(
                options={
                    'format': 'DD/MM/YYYY'
                },
                attrs={
                    'prepend': 'fa fa-calendar',
                },
            )
        }

You can add a lot of options to your DatePicker widget, have a look here and here for instance.

Update your template

Simply add {{ form.media }} in the template used to display your date. To display the date, you do not have to change anything: {{ form.deadline }}.

Note : do not forget to add missing resources if necessary! Like jQuery, Bootstrap4... Just have a look to resources specified in <head></head> in the doc.

Practical example (my own configuration)

For instance, here is how I do so any date can only be set with clicks (user can not type inside the date input):

# forms.py

import datetime
from allauth.account.forms import SignupForm
from django import forms
from django.utils.translation import ugettext_lazy as _
from tempus_dominus.widgets import DatePicker

sixteen_years_ago = datetime.date.today() - datetime.timedelta(days=16*365.24)
common_options_for_datetimepicker = {
    'icons': {
        'time': 'far fa-clock',
        'date': 'far calendar-alt',
        'up': 'fas fa-arrow-circle-up',
        'down': 'fas fa-arrow-circle-down',
        'previous': 'far fa-arrow-alt-circle-left fa-lg',
        'next': 'far fa-arrow-alt-circle-right fa-lg',
    },
    'widgetPositioning': {
        'vertical': 'bottom',
        'horizontal': 'left'
    },
    'ignoreReadonly': True,
}

class Signup_MixinForm(SignupForm):
    class Meta:
        abstract = True

class SignupRegular_Form(Signup_MixinForm):
    birth_date = forms.DateField(
        required=True,
        initial=sixteen_years_ago,
        widget=DatePicker(
            options={
                **common_options_for_datetimepicker,
                'format': 'D/MM/YYYY',
                'maxDate': sixteen_years_ago.strftime('%Y-%m-%d')
            },
            attrs={
                'prepend': 'fa fa-calendar',
                'size': 'large',
                'placeholder': _("Your birth date"),
                'readonly': 'readonly'
            },
        ),
    )

Upvotes: 1

Related Questions