169👍
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:
-
Define your own
ModelForm
subclass for your model (best to put it in forms.py in your app), and tell it to use theAdminDateWidget
/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()
-
Change your URLconf to pass
'form_class': ProductForm
instead of'model': Product
to the genericcreate_object
view (that’ll meanfrom my_app.forms import ProductForm
instead offrom my_app.models import Product
, of course). -
In the head of your template, include
{{ form.media }}
to output the links to the Javascript files. -
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.
67👍
As the solution is hackish, I think using your own date/time widget with some JavaScript is more feasible.
- [Django]-Timestamp fields in django
- [Django]-Charts in django Web Applications
- [Django]-Django switching, for a block of code, switch the language so translations are done in one language
14👍
I find myself referencing this post a lot, and found that the documentation defines a slightly less hacky way to override default widgets.
(No need to override the ModelForm’s __init__ method)
However, you still need to wire your JS and CSS appropriately as Carl mentions.
forms.py
from django import forms
from my_app.models import Product
from django.contrib.admin import widgets
class ProductForm(forms.ModelForm):
mydate = forms.DateField(widget=widgets.AdminDateWidget)
mytime = forms.TimeField(widget=widgets.AdminTimeWidget)
mydatetime = forms.SplitDateTimeField(widget=widgets.AdminSplitDateTime)
class Meta:
model = Product
Reference Field Types to find the default form fields.
- [Django]-Remove pk field from django serialized objects
- [Django]-How to show processing animation / spinner during ajax request?
- [Django]-Django urlsafe base64 decoding with decryption
13👍
My head code for 1.4 version(some new and some removed)
{% block extrahead %}
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/forms.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/base.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/global.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/widgets.css"/>
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/core.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/admin/RelatedObjectLookups.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.init.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/actions.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/calendar.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/admin/DateTimeShortcuts.js"></script>
{% endblock %}
- [Django]-Django gunicorn sock file not created by wsgi
- [Django]-How to solve "Page not found (404)" error in Django?
- [Django]-How to use MySQLdb with Python and Django in OSX 10.6?
12👍
Yep, I ended up overriding the /admin/jsi18n/ url.
Here’s what I added in my urls.py. Make sure it’s above the /admin/ url
(r'^admin/jsi18n', i18n_javascript),
And here is the i18n_javascript function I created.
from django.contrib import admin
def i18n_javascript(request):
return admin.site.i18n_javascript(request)
- [Django]-Django models: Only permit one entry in a model?
- [Django]-Row level permissions in django
- [Django]-Django: Get list of model fields?
10👍
Starting in Django 1.2 RC1, if you’re using the Django admin date picker widge trick, the following has to be added to your template, or you’ll see the calendar icon url being referenced through “/missing-admin-media-prefix/”.
{% 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>
- [Django]-What is the use of PYTHONUNBUFFERED in docker file?
- [Django]-Suddenly when running tests I get "TypeError: 'NoneType' object is not iterable
- [Django]-Django index page best/most common practice
8👍
For Django >= 2.0
Note: Using admin widgets for date-time fields is not a good idea as admin style-sheets can conflict with your site style-sheets in case you are using bootstrap or any other CSS frameworks. If you are building your site on bootstrap use my bootstrap-datepicker widget django-bootstrap-datepicker-plus.
Step 1: Add javascript-catalog
URL to your project’s (not app’s) urls.py
file.
from django.views.i18n import JavaScriptCatalog
urlpatterns = [
path('jsi18n', JavaScriptCatalog.as_view(), name='javascript-catalog'),
]
Step 2: Add required JavaScript/CSS resources to your template.
<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script type="text/javascript" src="{% static '/admin/js/core.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static '/admin/css/widgets.css' %}">
<style>.calendar>table>caption{caption-side:unset}</style><!--caption fix for bootstrap4-->
{{ form.media }} {# Form required JS and CSS #}
Step 3: Use admin widgets for date-time input fields in your forms.py
.
from django.contrib.admin import widgets
from .models import Product
class ProductCreateForm(forms.ModelForm):
class Meta:
model = Product
fields = ['name', 'publish_date', 'publish_time', 'publish_datetime']
widgets = {
'publish_date': widgets.AdminDateWidget,
'publish_time': widgets.AdminTimeWidget,
'publish_datetime': widgets.AdminSplitDateTime,
}
- [Django]-Access web server on VirtualBox/Vagrant machine from host browser?
- [Django]-How to perform OR condition in django queryset?
- [Django]-Django 2.0 – Not a valid view function or pattern name (Customizing Auth views)
7👍
Complementing the answer by Carl Meyer, I would like to comment that you need to put that header in some valid block (inside the header) within your template.
{% block extra_head %}
<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"/>
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="/media/admin/js/core.js"></script>
<script type="text/javascript" src="/media/admin/js/admin/RelatedObjectLookups.js"></script>
{{ form.media }}
{% endblock %}
- [Django]-How to query as GROUP BY in Django?
- [Django]-Migrating Django fixtures?
- [Django]-Django.db.utils.ProgrammingError: relation "bot_trade" does not exist
5👍
The below will also work as a last resort if the above failed
class PaymentsForm(forms.ModelForm):
class Meta:
model = Payments
def __init__(self, *args, **kwargs):
super(PaymentsForm, self).__init__(*args, **kwargs)
self.fields['date'].widget = SelectDateWidget()
Same as
class PaymentsForm(forms.ModelForm):
date = forms.DateField(widget=SelectDateWidget())
class Meta:
model = Payments
put this in your forms.py from django.forms.extras.widgets import SelectDateWidget
- [Django]-How does one make logging color in Django/Google App Engine?
- [Django]-IOS app with Django
- [Django]-Django rest framework change primary key to use a unqiue field
5👍
Another simple solution for Django 3 (3.2) in 2021 😉 cause andyw’s solution doesn’t work in Firefox…
{% load static %}
{% block extrahead %}
{{ block.super }}
<script type="text/javascript" src="{% static 'admin/js/cancel.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}">
<script src="{% url 'admin:jsi18n' %}"></script>
<script src="{% static 'admin/js/jquery.init.js' %}"></script>
<script src="{% static 'admin/js/core.js' %}"></script>
{{ form.media }}
{% endblock %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Сохранить">
</form>
and you’ll able to use your form.
example:
from django.contrib.admin import widgets
date_time = forms.SplitDateTimeField(widget=widgets.AdminSplitDateTime)
- [Django]-Django Model() vs Model.objects.create()
- [Django]-Does django with mongodb make migrations a thing of the past?
- [Django]-Django: why i can't get the tracebacks (in case of error) when i run LiveServerTestCase tests?
4👍
Here’s another 2020 solution, inspired by @Sandeep’s. Using the MinimalSplitDateTimeMultiWidget found in this gist, in our Form as below, we can use modern browser date and time selectors (via eg ‘type’: ‘date’). We don’t need any JS.
class EditAssessmentBaseForm(forms.ModelForm):
class Meta:
model = Assessment
fields = '__all__'
begin = DateTimeField(widget=MinimalSplitDateTimeMultiWidget())
- [Django]-How to combine multiple QuerySets in Django?
- [Django]-How does one make logging color in Django/Google App Engine?
- [Django]-Using JSON in django template
3👍
What about just assigning a class to your widget and then binding that class to the JQuery datepicker?
Django forms.py:
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['my_date_field'].widget.attrs['class'] = 'datepicker'
And some JavaScript for the template:
$(".datepicker").datepicker();
- [Django]-New url format in Django 1.9
- [Django]-Django, Models & Forms: replace "This field is required" message
- [Django]-VueJS + Django Channels
1👍
Updated solution and workaround for SplitDateTime with required=False:
forms.py
from django import forms
class SplitDateTimeJSField(forms.SplitDateTimeField):
def __init__(self, *args, **kwargs):
super(SplitDateTimeJSField, self).__init__(*args, **kwargs)
self.widget.widgets[0].attrs = {'class': 'vDateField'}
self.widget.widgets[1].attrs = {'class': 'vTimeField'}
class AnyFormOrModelForm(forms.Form):
date = forms.DateField(widget=forms.TextInput(attrs={'class':'vDateField'}))
time = forms.TimeField(widget=forms.TextInput(attrs={'class':'vTimeField'}))
timestamp = SplitDateTimeJSField(required=False,)
form.html
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="/admin_media/js/core.js"></script>
<script type="text/javascript" src="/admin_media/js/calendar.js"></script>
<script type="text/javascript" src="/admin_media/js/admin/DateTimeShortcuts.js"></script>
urls.py
(r'^admin/jsi18n/', 'django.views.i18n.javascript_catalog'),
- [Django]-How to run a celery worker with Django app scalable by AWS Elastic Beanstalk?
- [Django]-Django MEDIA_URL and MEDIA_ROOT
- [Django]-How to reset Django admin password?
1👍
I use this, it’s great, but I have 2 problems with the template:
- I see the calendar icons twice for every filed in template.
-
And for TimeField I have ‘Enter a valid date.‘
models.py
from django.db import models
name=models.CharField(max_length=100)
create_date=models.DateField(blank=True)
start_time=models.TimeField(blank=False)
end_time=models.TimeField(blank=False)
forms.py
from django import forms
from .models import Guide
from django.contrib.admin import widgets
class GuideForm(forms.ModelForm):
start_time = forms.DateField(widget=widgets.AdminTimeWidget)
end_time = forms.DateField(widget=widgets.AdminTimeWidget)
create_date = forms.DateField(widget=widgets.AdminDateWidget)
class Meta:
model=Guide
fields=['name','categorie','thumb']
- [Django]-Where can I find the error logs of nginx, using FastCGI and Django?
- [Django]-Django template includes slow?
- [Django]-Images from ImageField in Django don't load in template
0👍
In Django 10.
myproject/urls.py:
at the beginning of urlpatterns
from django.views.i18n import JavaScriptCatalog
urlpatterns = [
url(r'^jsi18n/$', JavaScriptCatalog.as_view(), name='javascript-catalog'),
.
.
.]
In my template.html:
{% load staticfiles %}
<script src="{% static "js/jquery-2.2.3.min.js" %}"></script>
<script src="{% static "js/bootstrap.min.js" %}"></script>
{# Loading internazionalization for js #}
{% load i18n admin_modify %}
<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script type="text/javascript" src="{% static "/admin/js/jquery.init.js" %}"></script>
<link rel="stylesheet" type="text/css" href="{% static "/admin/css/base.css" %}">
<link rel="stylesheet" type="text/css" href="{% static "/admin/css/forms.css" %}">
<link rel="stylesheet" type="text/css" href="{% static "/admin/css/login.css" %}">
<link rel="stylesheet" type="text/css" href="{% static "/admin/css/widgets.css" %}">
<script type="text/javascript" src="{% static "/admin/js/core.js" %}"></script>
<script type="text/javascript" src="{% static "/admin/js/SelectFilter2.js" %}"></script>
<script type="text/javascript" src="{% static "/admin/js/admin/RelatedObjectLookups.js" %}"></script>
<script type="text/javascript" src="{% static "/admin/js/actions.js" %}"></script>
<script type="text/javascript" src="{% static "/admin/js/calendar.js" %}"></script>
<script type="text/javascript" src="{% static "/admin/js/admin/DateTimeShortcuts.js" %}"></script>
- [Django]-How to convert JSON data into a Python object?
- [Django]-How to test "render to template" functions in django? (TDD)
- [Django]-Django storages: Import Error – no module named storages
0👍
My Django Setup : 1.11
Bootstrap: 3.3.7
Since none of the answers are completely clear, I am sharing my template code which presents no errors at all.
Top Half of template:
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block head %}
<title>Add Interview</title>
{% endblock %}
{% block content %}
<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/forms.css' %}"/>
<link rel="stylesheet" type="text/css" href="{% static 'admin/css/widgets.css' %}"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
<script type="text/javascript" src="{% static 'js/jquery.js' %}"></script>
Bottom Half:
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{% static 'admin/js/vendor/jquery/jquery.min.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}"></script>
<script type="text/javascript" src="{% static 'admin/js/actions.min.js' %}"></script>
{% endblock %}
- [Django]-Is it bad to have my virtualenv directory inside my git repository?
- [Django]-Django ManyToMany filter()
- [Django]-Django annotation with nested filter
0👍
June 3, 2020 (All answers didn’t worked, you can try this solution I used. Just for TimeField)
Use simple Charfield
for time fields (start and end in this example) in forms.
forms.py
we can use Form
or ModelForm
here.
class TimeSlotForm(forms.ModelForm):
start = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'HH:MM'}))
end = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'HH:MM'}))
class Meta:
model = TimeSlots
fields = ('start', 'end', 'provider')
Convert string input into time object in views.
import datetime
def slots():
if request.method == 'POST':
form = create_form(request.POST)
if form.is_valid():
slot = form.save(commit=False)
start = form.cleaned_data['start']
end = form.cleaned_data['end']
start = datetime.datetime.strptime(start, '%H:%M').time()
end = datetime.datetime.strptime(end, '%H:%M').time()
slot.start = start
slot.end = end
slot.save()
- [Django]-Django related_name for field clashes
- [Django]-Unittest Django: Mock external API, what is proper way?
- [Django]-How do I POST with jQuery/Ajax in Django?
0👍
The most cleanest way (tested with Django 3.2):
from django.contrib import admin
from django.contrib.admin.widgets import AdminSplitDateTime
from django import forms
class MyCustomForm(forms.ModelForm):
custom_datetime = forms.SplitDateTimeField(widget=AdminSplitDateTime())
class Meta:
model = MyModel
fields = ("custom_datetime",)
class MyModelAdmin(admin.ModelAdmin):
def my_custom_admin_view(self, request):
form = MyCustomForm()
admin_form = admin.helpers.AdminForm(form, [], {}, model_admin=self)
media = self.media + admin_form.media
context = {
"media": media,
"form": form,
}
return render(request, "my_custom_template.html", context)
In the my_custom_template.html
:
{% extends "admin/base.html" %}
{% block extrastyle %}
{{ block.super }}
{{ media }}
{% endblock %}
{% block content %}
<form method="post">
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
{% endblock %}
- [Django]-Django create userprofile if does not exist
- [Django]-Django index page best/most common practice
- [Django]-How to implement followers/following in Django