Neara
Neara

Reputation: 3781

Django Forms - DateTime field show date only

I have a following model:

class Sponsorship(models.Model):
    sponsor = models.ForeignKey(Sponsor, related_name='sponsorships')
    start_datetime = models.DateTimeField(null=True, blank=True)
    end_datetime = models.DateTimeField(null=True, blank=True)

and form for the model looks like this:

class SponsorshipForm(ModelForm):

    class Meta:
        model = Sponsorship
        fields = ('start_datetime', 'end_datetime')
        widgets = {
            'start_datetime': forms.DateTimeInput(attrs={'class':
                                                             'form-control'}),
            'end_datetime': forms.DateTimeInput(attrs={'class':
                                                           'form-control'}),
        }



SponsorShipsFormSet = inlineformset_factory(Sponsor, Sponsorship,
                                                form=SponsorshipForm, extra=2)

In a view i do the usual:

SponsorShipsFormSet(instance=self.object)

But when the form is rendered, datetime input fields have only date for value, without the time.

Why is the form not being instantiated with date and time?

Edit

I printed, in template, the value of the input field:

{{ form.start_datetime.value }}

and it does have the datetime value as it should.

Upvotes: 0

Views: 1268

Answers (1)

Neara
Neara

Reputation: 3781

Ok, this was an insight of one in a million!

The cause of all this fuss was from settings DATETIME_INPUT_FORMATS.

What i had before:

DATETIME_INPUT_FORMATS = (
    '%d %B %Y',                # '05 March 2014'
    '%d %B %Y - %H:%M',        # '05 March 2014 - 08:07'
    '%d %B %Y - %H:%M:%S',     # '05 March 2014 - 08:07:59'
    '%d %B %Y - %H:%M:%S.%f',  # '05 March 2014 - 08:07:59.0001'

    '%d/%m/%Y %H:%M:%S.%f',    # '25/10/05 14:30:59.000200'
    '%d/%m/%Y %H:%M:%S',       # '25/10/05 14:30:59'
    '%d/%m/%Y %H:%M',          # '25/10/05 14:30'
    '%d/%m/%Y',                # '25/10/05'

    '%d-%m-%Y %H:%M:%S.%f',    # '25-10-05 14:30:59.000200'
    '%d-%m-%Y %H:%M:%S',       # '25-10-05 14:30:59'
    '%d-%m-%Y %H:%M',          # '25-10-05 14:30'
    '%d-%m-%Y',                # '25-10-05'

    '%Y-%m-%d %H:%M:%S.%f',    # '2006-10-25 14:30:59.000200'
    '%Y-%m-%d %H:%M:%S',       # '2006-10-25 14:30:59'
    '%Y-%m-%d %H:%M',          # '2006-10-25 14:30'
    '%Y-%m-%d',                # '2006-10-25'

    '%m/%d/%Y %H:%M:%S.%f',    # '10/25/2006 14:30:59.000200'
    '%m/%d/%Y %H:%M:%S',       # '10/25/2006 14:30:59'
    '%m/%d/%Y %H:%M',          # '10/25/2006 14:30'
    '%m/%d/%Y',                # '10/25/2006'

    '%m/%d/%y %H:%M:%S.%f',    # '10/25/06 14:30:59.000200'
    '%m/%d/%y %H:%M:%S',       # '10/25/06 14:30:59'
    '%m/%d/%y %H:%M',          # '10/25/06 14:30'
    '%m/%d/%y',                # '10/25/06'
)

What fixed the issue i had:

DATETIME_INPUT_FORMATS = (
    '%d %B %Y - %H:%M:%S.%f',  # '05 March 2014 - 08:07:59.0001'
    '%d %B %Y - %H:%M:%S',     # '05 March 2014 - 08:07:59'
    '%d %B %Y - %H:%M',        # '05 March 2014 - 08:07'
    '%d %B %Y',                # '05 March 2014' <- this line was first before

    '%d/%m/%Y %H:%M:%S.%f',    # '25/10/05 14:30:59.000200'
    '%d/%m/%Y %H:%M:%S',       # '25/10/05 14:30:59'
    '%d/%m/%Y %H:%M',          # '25/10/05 14:30'
    '%d/%m/%Y',                # '25/10/05'

    '%d-%m-%Y %H:%M:%S.%f',    # '25-10-05 14:30:59.000200'
    '%d-%m-%Y %H:%M:%S',       # '25-10-05 14:30:59'
    '%d-%m-%Y %H:%M',          # '25-10-05 14:30'
    '%d-%m-%Y',                # '25-10-05'

    '%Y-%m-%d %H:%M:%S.%f',    # '2006-10-25 14:30:59.000200'
    '%Y-%m-%d %H:%M:%S',       # '2006-10-25 14:30:59'
    '%Y-%m-%d %H:%M',          # '2006-10-25 14:30'
    '%Y-%m-%d',                # '2006-10-25'

    '%m/%d/%Y %H:%M:%S.%f',    # '10/25/2006 14:30:59.000200'
    '%m/%d/%Y %H:%M:%S',       # '10/25/2006 14:30:59'
    '%m/%d/%Y %H:%M',          # '10/25/2006 14:30'
    '%m/%d/%Y',                # '10/25/2006'

    '%m/%d/%y %H:%M:%S.%f',    # '10/25/06 14:30:59.000200'
    '%m/%d/%y %H:%M:%S',       # '10/25/06 14:30:59'
    '%m/%d/%y %H:%M',          # '10/25/06 14:30'
    '%m/%d/%y',                # '10/25/06'
)

So, the insight is:

When django renders datetimes in forms, it reads from DATETIME_INPUT_FORMATS and uses the first format that fits. Therefore, formats should go from the one with most details to one with least details.

On the other hand, when django reads datetime input from the client, it goes through all DATETIME_INPUT_FORMATS until it finds the one that fits and if not, the datetime will be invalid.

Upvotes: 1

Related Questions