Using Django Time/Date Widgets in Custom Form

Using Django time/date widgets in custom form

The growing complexity of this answer over time, and the many hacks required, probably ought to caution you against doing this at all. It's relying on undocumented internal implementation details of the admin, is likely to break again in future versions of Django, and is no easier to implement than just finding another JS calendar widget and using that.

That said, here's what you have to do if you're determined to make this work:

  1. Define your own ModelForm subclass for your model (best to put it in forms.py in your app), and tell it to use the AdminDateWidget / AdminTimeWidget / AdminSplitDateTime (replace 'mydate' etc with the proper field names from your model):

     from django import forms
    from my_app.models import Product
    from django.contrib.admin import widgets

    class ProductForm(forms.ModelForm):
    class Meta:
    model = Product
    def __init__(self, *args, **kwargs):
    super(ProductForm, self).__init__(*args, **kwargs)
    self.fields['mydate'].widget = widgets.AdminDateWidget()
    self.fields['mytime'].widget = widgets.AdminTimeWidget()
    self.fields['mydatetime'].widget = widgets.AdminSplitDateTime()
  2. Change your URLconf to pass 'form_class': ProductForm instead of 'model': Product to the generic create_object view (that'll mean from my_app.forms import ProductForm instead of from my_app.models import Product, of course).

  3. In the head of your template, include {{ form.media }} to output the links to the Javascript files.

  4. And the hacky part: the admin date/time widgets presume that the i18n JS stuff has been loaded, and also require core.js, but don't provide either one automatically. So in your template above {{ form.media }} you'll need:

     <script type="text/javascript" src="/my_admin/jsi18n/"></script>
    <script type="text/javascript" src="/media/admin/js/core.js"></script>

You may also wish to use the following admin CSS (thanks Alex for mentioning this):

    <link rel="stylesheet" type="text/css" href="/media/admin/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="/media/admin/css/base.css"/>
<link rel="stylesheet" type="text/css" href="/media/admin/css/global.css"/>
<link rel="stylesheet" type="text/css" href="/media/admin/css/widgets.css"/>

This implies that Django's admin media (ADMIN_MEDIA_PREFIX) is at /media/admin/ - you can change that for your setup. Ideally you'd use a context processor to pass this values to your template instead of hardcoding it, but that's beyond the scope of this question.

This also requires that the URL /my_admin/jsi18n/ be manually wired up to the django.views.i18n.javascript_catalog view (or null_javascript_catalog if you aren't using I18N). You have to do this yourself instead of going through the admin application so it's accessible regardless of whether you're logged into the admin (thanks Jeremy for pointing this out). Sample code for your URLconf:

(r'^my_admin/jsi18n', 'django.views.i18n.javascript_catalog'),

Lastly, if you are using Django 1.2 or later, you need some additional code in your template to help the widgets find their media:

{% load adminmedia %} /* At the top of the template. */

/* In the head section of the template. */
<script type="text/javascript">
window.__admin_media_prefix__ = "{% filter escapejs %}{% admin_media_prefix %}{% endfilter %}";
</script>

Thanks lupefiasco for this addition.

Django calendar widget in a custom form

I figured it out, thanks to Dave S. and a number of old posts on this topic. My successful method:

Create a custom form.

At the top, import the admin widgets using from django.contrib.admin.widgets import AdminDateWidget. Then, add the different fields of your form, using my_field = DateField(widget = AdminDateWidget) whenever you want to use the date widget.

Create your form template

Place the following toward the top to include the appropriate css/js files:

{% load i18n admin_modify adminmedia %}
{% block extrahead %}{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/base.css" />
<link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/widgets.css" />
<script type="text/javascript" src="/jsi18n/"></script>
<script type="text/javascript" src="{% admin_media_prefix %}js/core.js"></script>
{{ form.media }}
{% endblock %}

Note: You do not necessarily need all of this, depending upon your version of Django and how you are implementing the form fields. this is what I found that I needed to use the widgets.

Now just output your form like normal, and the JS should automatically convert it to a date field. Enjoy!

How to use a DatePicker in a ModelForm in django?

This is the expected behavior. A DateInput widget [Django-doc] is just a <input type="text"> element with an optional format parameter.

You can make use of a package, like for example django-bootstrap-datepicker-plus [pypi]
, and then define a form with the DatePickerInput:

from bootstrap_datepicker_plus import DatePickerInput
class MembershipForm(ModelForm):
class Meta:
model = Membership
fields = ['owner', 'start_date', 'type']
widgets = {
'start_date': DatePickerInput
}

In the template you will need to render the media of the form and load the bootstrap css and javascript:

{% load bootstrap4 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{{ form.media }}

<form class="container" action="" method="POST">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">Submit</button>
</form>

Save custom Date and Time in created_at field Django

Import:

from datetime import datetime, timezone

In models.py:

created_at = models.DateTimeField(auto_now=False, auto_now_add=False,blank=True, null=True)

this will allow your created_at field exist with Null value (being empty)

In views.py:

def time_function(request):
#get your object
object = Object.objects.get(xx=zz)

#this will create date and time object with your current timezone
date_time_now = datetime.now(tz=timezone.utc)

#assign time to your objects field
object.created_at = date_time_now
object.save()

How to use the date picker used in django 1.11 admin site in custom form?

from django.forms.extras.widgets import SelectDateWidget
from django.forms import ModelForm
from models import SampleModel

class SampleModelForm(ModelForm):
class Meta:
model = SampleModel
widgets = {'date_field': SelectDateWidget()}}


Related Topics



Leave a reply



Submit