Reputation: 116
Edit: it seems that when we use a DateTimeField
in django, it expects two inputs, one with the date, and one with the time like this:
So I'll just create two fields, one for the time and one for the date, will post an answer if it works as expected.
I created a custom widget in order to replace the default django's datetime picker in my administration site.
To do so I followed these instructions but it ends up like this when I click save button:
I have no other specific errors in the logs.
For more details, here is the code:
settings.py:
DATE_INPUT_FORMATS = ['%d/%m/%Y %H:%M']
app/templates/widgets/xdsoft_datetimepicker.html
{% include "django/forms/widgets/input.html" %}
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<!-- XDSoft DateTimePicker -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.css" integrity="sha256-DOS9W6NR+NFe1fUhEE0PGKY/fubbUCnOfTje2JMDw3Y=" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js" integrity="sha256-FEqEelWI3WouFOo2VWP/uJfs1y8KJ++FLh2Lbqc8SJk=" crossorigin="anonymous"></script>
<script>
$(function () {
$("input[name='{{ widget.name }}']").datetimepicker({
format: 'd/m/Y H:i',
});
});
</script>
app/models.py:
class DatesAndDates(models.Model):
date_time_1 = models.DateTimeField()
app/forms.py:
class DateForm(forms.ModelForm):
class Meta:
model = DatesAndDates
widgets = {
"date_time_1": XDSoftDateTimePickerInput(
)
}
fields=["date_time_1"]
And Finally app/admin.py:
@admin.register(DatesAndDates)
class DatesAndDatesAdmin(admin.ModelAdmin):
form = DateForm
list_display = ["date_time_1"]
Before trying this I just used a Charfield for the date and time and added the jQuery script by overriding the change_form.html template but i failed at converting the datetime string to a valid datetime type.
Thanks for reading and for the help.
Upvotes: 1
Views: 881
Reputation: 31
To avoid multiple css/js loads, you can pass your media in your widget class like this:
class XDSoftDatePickerInput(DateInput):
...
class Media:
css = {
"all": (
'https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.css',
)
}
js = (
"https://code.jquery.com/jquery-3.4.1.min.js",
'https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js',
)
Upvotes: 0
Reputation: 116
As i said in the edit:
When we use a models.DateTimeField
Dango expects datas from two formfields, one for the date and one for the time. So as i said i created two fields in my model, one models.DateField
and one models.TimeField
. And here is the method i used to create my own Widget in my app:
app/widget.py:
from django.forms import DateInput, TimeInput
# Overriding DateInput and TimeInput's template with my own one
class XDSoftDatePickerInput(DateInput):
template_name = 'widgets/xdsoft_datetimepicker.html'
class XDSoftTimePickerInput(TimeInput):
template_name = 'widgets/xdsoft_datetimepicker.html'
app/templates/widgets/xdsoft_datetimepicker.html
{% include "django/forms/widgets/input.html" %}
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<!-- XDSoft DateTimePicker -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.min.css" integrity="sha256-DOS9W6NR+NFe1fUhEE0PGKY/fubbUCnOfTje2JMDw3Y=" crossorigin="anonymous" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js" integrity="sha256-FEqEelWI3WouFOo2VWP/uJfs1y8KJ++FLh2Lbqc8SJk=" crossorigin="anonymous"></script>
<script>
$.datetimepicker.setLocale('fr');
widget_name = '{{ widget.name }}'
if (~widget_name.indexOf("date")){
$(function () {
$("input[name='{{ widget.name }}']").datetimepicker({
format: 'd/m/Y',
timepicker:false,
});
});
}
else{
$(function () {
$("input[name='{{ widget.name }}']").datetimepicker({
format: 'H:i',
datepicker:false,
});
});
}
</script>
app/models.py:
class Event(models.Model):
date_begin = models.DateField(verbose_name="Date début de l'évènement")
hour_begin = models.TimeField(verbose_name="Heure début de l'évènement")
date_end = models.DateField(blank=True, null=True, verbose_name="Date de fin de l'évènement")
hour_end = models.TimeField(blank=True, null=True, verbose_name="Heure de Fin de l'évènement")
app/forms.py:
class EventForm(forms.ModelForm):
class Meta:
model = Event
widgets = {
"date_begin": XDSoftDatePickerInput(
),
"date_end": XDSoftDatePickerInput(
),
"hour_begin": XDSoftTimePickerInput(
),
"hour_end": XDSoftTimePickerInput(
)
}
fields='__all__'
And voilà:
But there is a problem here: Every time you'll use the widget, the all jquery script will be included in your page...
Upvotes: 0