Why is Django widgets for TimeInput not showing

1.1k Views Asked by At

I'm trying to create a TimeInput field in a form and noticed that the widget isn't showing correctly. But when I check the localhost:8000/admin, I see the widget showing up correctly.

My code is as follows. For models.py,

class TimeLimit(models.Model):
    before = models.TimeField(blank=True, default=time(7, 0)) # 7AM
    after = models.TimeField(blank=True, default=time(23, 0)) # 11PM

For views.py,

class UpdateTimeLimitView(LoginRequiredMixin, FormView):
    model = TimeLimit
    template_name = 'accounts/update_time_limit.html'
    form_class = UpdateTimeLimitForm

    def get_success_url(self):
        return reverse_lazy('accounts:user_profile') + '?username=' + self.request.GET['username']

    def get_context_data(self, **kwargs):
        data = super(UpdateTimeLimitView, self).get_context_data(**kwargs)
        data['username'] = self.request.GET['username']
        return data

For forms.py,

class UpdateTimeLimitForm(forms.Form):
    time_error = {'required': 'This field is required.',
                  'invalid': 'Please enter valid Hour:Minute values.'}

    before = forms.TimeField(widget=forms.TimeInput(format='%H:%M'))
    after = forms.TimeField(widget=TimeInput(format='%H:%M'))

    class Meta:
        model = TimeLimit

Finally, the relevant part for fields in update_time_limit.html,

<div class="container">
    <form method="post">
        {% csrf_token %}
        <p>
        {% for field in form %}
            {{ field.errors }}
            <label for="{{ field.id_for_label }}">{{ field.label }}({{ field.help_text }}):</label>
            <br />
            {{ field }}<br /><br /> and
        {% endfor %}
        </p>
        <input class="btn btn-primary done-btn" type="submit" value="Update Time Limit">
    </form>
</div>

Is there anything that I'm missing or doing wrong? Thank you.

2

There are 2 best solutions below

1
On BEST ANSWER

The Django admin uses AdminTimeWidget to display time fields, not the TimeInput widget that you are using in your code.

There isn't a documented way to reuse the AdminTimeWidget outside of the Django admin. Getting it to work is very hacky (see the answer on this question, which is probably out of date), so it's probably better to use a different widget.

0
On

convert datetime.time(7, 0) to string work for me.

data['before'] = data['before'].strftime('%H:%M:%S')