How to set data calendar widget for DateField and DateTimeField with format day-month-year (dd/mm/yyyy)?

Hi,
I try to do as the link below.
https://djangotricks.blogspot.com/2019/10/working-with-dates-and-times-in-forms.html

I can set this calendar widget on form but format to enter data turn into mm/dd/yyyy H:M AM/PM . I want another format.
However ,I want the format like dd/mm/yyyy H:M. Hour is 1-23, It is local date time format of my country.

I have gotten stuck for this issue for a while ,I have tried to change format as my need in form.py on datefield both widget and class . , but it is not ok at all. It still show mm/dd/yyyy and what is worse is that when I click edit item, it cannot set this field on form. (see in picture below).

In general, python store data date type as YYYY-mm-dd fomat
but we get it to show as desired like dd/mm/yyyy using strftime function.

1.how to fix this problem ?
2.Is it ok if I need to use a third-party package?, if so please recommend Django datetime-widget.
https://pypi.org/project

I use boostrap, it is default template from visual studio 2019 professtional edition.
Bootstrap v3.0.0,Copyright 2013 Twitter, Inc

These are my files to do.
models.py

class XYZ_TestData(models.Model):
   my_title = models.CharField('XYZ Title',max_length=255)
   my_date= models.DateField('XYZ Date')
   my_date_time = models.DateTimeField('XYZ DateTime')
   my_active = models.BooleanField(default=True)
   my_des = models.TextField('XYZ Description',default='Test')

forms.py

class XYZ_DateInput(forms.DateInput):
    input_type = "date"
    def __init__(self, **kwargs):
        kwargs["format"] = "%Y-%m-%d"
        # kwargs["format"] = "%d-%m-%Y"
        super().__init__(**kwargs)

class XYZ_DateTimeInput(forms.DateTimeInput):
    input_type = "datetime-local"
    #input_type = "datetime"
    def __init__(self, **kwargs):
        kwargs["format"] = "%Y-%m-%dT%H:%M"
        super().__init__(**kwargs)

class XYZ_TestDataForm(forms.ModelForm):
    class Meta:
        model =XYZ_TestData
        fields = '__all__'
        widgets = {
            'my_date':XYZ_DateInput(format=["%Y-%m-%d"],),
            # 'my_date': XYZ_DateInput(format=["%d-%m-%Y"], ),
            'my_date_time': XYZ_DateTimeInput(format=["%Y-%m-%dT%H:%M", "%Y-%m-%d %H:%M"],),
            'my_des': forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),

        }


views.py

def manage_xyz(request, id=0):
    xyzList=XYZ_TestData.objects.all()
    if request.method == "GET":
        if id == 0:  # new detail
            form =  XYZ_TestDataForm()
            form_mode = 'new'
        else:  # edit
            xyz = get_object_or_404(XYZ_TestData, pk=id)
            form = XYZ_TestDataForm(instance=xyz)
            form_mode = 'update'

    else:  # post data both adding and updating
        if id == 0:  # save from  new
            form = XYZ_TestDataForm(request.POST)
        else:  # save from  edit
            xyz = get_object_or_404(XYZ_TestData, pk=id)
            form = XYZ_TestDataForm(request.POST, instance=xyz)
        if form.is_valid():
            form.save()
        else:
            messages.error(request, form.errors)
        return redirect('manage_xyz')

    return render(request, "app/test_my_xyz.html",
                  {'form': form,  'xyzList': xyzList, 'mode': form_mode})



test_my_xyz.html


{% load crispy_forms_tags %}
{% block content %}
    <h2>Test Crud</h2>
    <form action="" method="post" autocomplete="off">
        {% csrf_token %}
             <div class="well">
        <div class="container-fluid">
            <div class="row">
                <div class="col-md-3">{{ form.my_title | as_crispy_field }}</div>
                <div class="col-md-3">{{ form.my_date | as_crispy_field }}</div>
                <div class="col-md-3">{{ form.my_date_time| as_crispy_field }}</div>
                <div class="col-md-3">{{ form.my_active| as_crispy_field }}</div>

            </div>
            <div class="row">
                <div class="col-md-12">{{ form.my_des|as_crispy_field }}</div>
            </div>
              <div class='row text-center'>
                <div class="col-md-12 center-block">
                    <input type="submit" value="Save XYZ" class="btn btn-success" >

                </div>
            </div>
        </div>
             </div>
    </form>
        <h2>List XYZ</h2>
    <table class="table table-striped table-hover">

        <tr>
            <th scope="col">ID</th>
            <th scope="col">Title</th>
            <th scope="col">Date</th>
            <th scope="col">DateTime</th>
            <th scope="col">Active</th>

        </tr>

        <tbody>
        {% for xyz in xyzList %}
            <tr>
                <th scope="row">{{ xyz.id }}</th>
                <td>{{ xyz.my_title }}</td>
                <td>{{ xyz.my_date }}</td>
                <td>{{ xyz.my_date_time }}</td>
                <td>{{ xyz.my_active }}</td>
                <td><a href="{% url 'manage_xyz' xyz.id %}" class="btn btn-link">Edit</a></td>

            </tr>
        {% endfor %}
        <tbody>
    </table>
    
{% endblock %}



urls.py

    path('xyz/<int:id>/', views.manage_xyz, name='manage_xyz'),
    path('xyz/', views.manage_xyz, name='manage_xyz'),

Thank you for any help.
Pongthorn

I’m not following exactly what you’re looking for here.

Are you looking to allow for input of a date in a specific format, or to output a data in that format?

If you’re looking to allow for a date to be entered in a specific format, see any or all of:

Your choice among these is going to depend upon how “universal” you want this to be across your application. The settings will be global, but can also be overridden in specific forms using the input_formats attribute.

I want to look for how to set input format on calendar widget on form.
I want dd/mm/yyyy for date and dd/mm/yyyy H:M for datetime
but it turn into as figure , it provide mm/dd/yyyy and dd/mm/yyyy H:M AM/PM

take a look at the sample code forms.py
I create custom class date and datetime and apply them as widget inXYZ_TestDataForm.
I am looking for how to set date and datetime to be entered in a specific format dd/mm/yyy and dd/mm/yyyy H:M respectively.

As I see your reference
format-localization
it has been set USE_L10N = True in settings.py
I don’t know where to be able to set localize=True on file forms.py

date-format
I don’t see format ‘%d/%m/%Y’

Right - if you want that setting, then you need to add it to your settings. (You can either add it to the setting, or you can replace the default with only what you want to allow.)

If I want to use format dd/mm/yyyy and dd/mm/yyy H:M throughout this project.
Do I have to set it in settings.py?

How to set in in settings.py. please show your sample?
this is some parts in settings.py. I don’t know how to set in this files.

The settings.py file would seem to be the logical place for something that applies throughout your entire application, wouldn’t it? It is the place for your project’s configuration item.

You’ve seen what the default looks like - you’re just setting the value of a variable in a list.

Give it a try, and if it doesn’t work, post what you’ve tried and the error message you’ve received.

I try it but there is nothing better.
the input format of my calendar widget remains the same mm/dd/YYYY.

You can remmend other picker -calendar that I have used it , maybe it may better.

https://pypi.org/

this is a newly added value in settings.py , both red highlight in picture are my required format.

The carlendar widget still set mm/dd/yyyy

I am not sure whether to set format in forms.py or not .

I am getting stunned right now.
please see forms.py

class XYZ_DateInput(forms.DateInput):
    input_type = "date"
    def __init__(self, **kwargs):
        kwargs["format"] = "%Y-%m-%d"
        # kwargs["format"] = '%d/%m/%Y'
        super().__init__(**kwargs)

class XYZ_DateTimeInput(forms.DateTimeInput):
    input_type = "datetime-local"
    def __init__(self, **kwargs):
        # kwargs["format"] = "%Y-%m-%d %H:%M"
        kwargs["format"] = "%Y-%m-%dT%H:%M"
        # kwargs["format"] = '%d/%m/%Y %H:%M'
        super().__init__(**kwargs)

class XYZ_TestDataForm(forms.ModelForm):
    class Meta:
        model =XYZ_TestData
        is_localized = True
        fields = '__all__'
        widgets = {
            'my_date': XYZ_DateInput(format=["%Y-%m-%d"], ),
            # 'my_date':XYZ_DateInput(format=['%d/%m/%Y'],),

            'my_date_time': XYZ_DateTimeInput(format=["%Y-%m-%dT%H:%M", "%Y-%m-%d %H:%M"],),
            # 'my_date_time': XYZ_DateTimeInput(format=['%d/%m/%Y %H:%M'], ),
            'my_des': forms.Textarea(attrs={'rows': 5, 'class': 'form-control'}),

        }




Is that some 3rd-party JavaScript based widget you’re using? If so, it may be an issue of that widget needing to be configured differently.

No, There is no widget from third-party java script, the calendar widget as my figure shown , it have been set from class XYZ_DateInput and XYZ_DateTimeInput
both are set input_type = “date” and input_type = “datetime-local” respectively.

you can see in code form.py that I pasted in prev reply.

Your picture is not of a standard HTML widget. There’s something being rendered using JavaScript that would be handling that style of calendar entry.
Please show all script tags from this template where the page is being loaded.

layout.html it use boostrap3 , you are assumming that it result from java script in boostrap3


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    {% load static %}


    {#  <link rel="stylesheet" type="text/css" href="{% static 'app/content/bootstrap.min.css' %}" />#}
    <link rel="stylesheet" type="text/css" href="{% static 'app/content/bootstrap.min.css' %}"/>
    <link rel="stylesheet" type="text/css" href="{% static 'app/content/site.css' %}"/>

    <script src="{% static 'app/scripts/ckeditor/ckeditor.js' %}"></script>
    <script src="{% static 'app/scripts/modernizr-2.6.2.js' %}"></script>
</head>
{#<script src="https://code.jquery.com/jquery-3.5.1.js"></script>#}
{#<script src="{% static 'app/scripts/jquery-1.10.2.js' %}"></script>#}
<script src="{% static 'app/scripts/jquery-3.5.1.js' %}"></script>

<script src="{% static 'app/scripts/bootstrap.js' %}"></script>
<script src="{% static 'app/scripts/respond.js' %}"></script>
{% block scripts %}{% endblock %}

mainhtml file.


{% extends "app/layout.html" %}
{% load crispy_forms_tags %}

{% block content %}
    <h2>Test Crud</h2>
    <form action="" method="post" autocomplete="off">
        {% csrf_token %}
        <div class="well">
            <div class="container-fluid">
                <div class="row">
                    <div class="col-md-3">{{ form.my_title | as_crispy_field }}</div>


                        <div class="col-md-3">{{ form.my_date | as_crispy_field }}</div>


                     <div class="col-md-3">{{ form.my_date_time| as_crispy_field }}</div>

                    <div class="col-md-3">{{ form.my_active| as_crispy_field }}</div>

                </div>
                <div class="row">
                    <div class="col-md-12">{{ form.my_des|as_crispy_field }}</div>
                </div>
                <div class='row text-center'>
                    <div class="col-md-12 center-block">
                        <input type="submit" value="Save XYZ" class="btn btn-success">

                    </div>
                </div>
            </div>
        </div>
    </form>
    <h2>List XYZ</h2>
    <table class="table table-striped table-hover">

        <tr>
            <th scope="col">ID</th>
            <th scope="col">Title</th>
            <th scope="col">Date</th>
            <th scope="col">DateTime</th>
            <th scope="col">Active</th>

        </tr>

        <tbody>
        {% for xyz in xyzList %}
            <tr>
                <th scope="row">{{ xyz.id }}</th>
                <td>{{ xyz.my_title }}</td>
                <td>{{ xyz.my_date }}</td>
                <td>{{ xyz.my_date_time }}</td>
                <td>{{ xyz.my_active }}</td>
                <td><a href="{% url 'manage_xyz' xyz.id %}" class="btn btn-link">Edit</a></td>

            </tr>
        {% endfor %}
        <tbody>
    </table>

{% endblock %}


I’m not assuming anything. I’m trying to determine what JavaScript is creating that visual effect for date entry.

I may try the following package in next week orderly.
Do you have any suggstion?

https://pypi.org/project/django-datetime-widget2/

https://pypi.org/project/django-bootstrap-daterangepicker/

https://pypi.org/project/bootstrap3-datetime/

Sorry, no suggestion from among that group. We use jQuery UI datepicker, it’s the only one I have any familiarity with.

I am wondering, how to bring DateTime , date picker in admin section to use in my form.

I seem to remember a discussion here in the forum a little while ago about using the Admin page widgets in your own templates. If you search through the old threads, I’m sure you’ll find it.

OK , I will look up more in forum.
Thank you for helping along.

You are mentioning this topic?
https://forum.djangoproject.com/t/add-default-datetime-form-widget-in-a-custom-datetime-form/6414

if yes, I will study more in the coming weeken.

Yep, that’s the one. The links in there should get you to where the information is.

1 Like

Hi there,

The link topic doesn’t have a solution to use Admin page widget. I gave it a try and it worked. Basically, there are 3 parts to make it work.

Part 1 - Model & form
The key is to set up 2 attributes date and time as shown below

from django.db import models
class Quote(models.Model):
    id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
    owner = models.ForeignKey(Profile, null=True, blank=True, on_delete=models.SET_NULL)
    content = models.TextField(max_length=1000, null=True, blank=False)
    author = models.CharField(max_length=200, blank=True, null=True)
    description = models.TextField(max_length=1000, blank=True, null=True)
    date = models.DateField(blank=True, null=True)
    time = models.TimeField(blank=True, null=True)
    created = models.DateTimeField(auto_now_add=True)

forms

from django.contrib.admin.widgets import AdminDateWidget, AdminTimeWidget, AdminSplitDateTime

class QuoteForm(ModelForm):
    class Meta:
        model = Quote
        fields = ['content', 'author', 'description', 'date', 'time']
        widgets = {
            'date': AdminDateWidget(),
            'time': AdminTimeWidget(),
        }

Part 2 - in your template HTML - please include these 3 lines in the head section to load
required JS and CSS for the form’s date and time fields.

<script src="{% url 'js-catlog' %}"></script>
<script src="{% static '/admin/js/core.js' %}"></script>
<link rel="stylesheet" href="{% static 'admin/css/base.css' %}">
<link rel="stylesheet" href="{% static 'admin/css/widgets.css' %}">

<form method="POST" enctype="multipart/form-data">
    {% csrf_token%}
    {{ form.media }}
    {{ form.as_p }}
    <input type="submit" value="submit"/>
</form>

Part 3 - adding this path, along with other paths, to the project’s urls

from django.views.i18n import JavaScriptCatalog

urlpatterns = [
    path('jsi18n', JavaScriptCatalog.as_view(), name='js-catlog'),
]

Then it should render the date and time picker exactly the styling of the admin panel.

1 Like