8

How to format DateTimeField in Admin according to localtime and timezone ?

My settings.py:

    TIME_ZONE = 'Europe/Bratislava'
    LANGUAGE_CODE = 'en-us'
    USE_I18N = True
    USE_L10N = True
    USE_TZ = True

pytz package is installed.

model:

class Material(models.Model):
    category = models.ForeignKey(Category, null=True, blank=True) 
    code = models.CharField(max_length=10)
    description = models.CharField(max_length=30, blank=True, null=True)
    modified = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)

Also tried some date formatting in settings, none of this changed the way datetime object is converted to string in admin list display:

DATETIME_FORMAT = 'd N Y'
DATE_FORMAT = 'd N Y'

In database datetime is stored correctly, "2012-11-20 08:57:15.901341+01". But when displayed in admin, it is always in UTC.

I can prepare methods in ModelAdmin to handle format, but that is not really DRY as I'd like to my admin classes look like:

from django.utils.timezone import localtime

class MaterialAdmin(admin.ModelAdmin):
    list_display = ('code', 'modified_local', 'created')

    def modified_local(self, row):
        return localtime(row.modified)
    modified_local.admin_order_field = 'modified'
    modified_local.short_description = 'Modified'
Edke
  • 161
  • 1
  • 1
  • 6
  • 2
    What does the `from django.utils.formats import localize; localize(localtime(row.modified))` output in pyshell? – okm Nov 20 '12 at 11:53
  • >>> row.modified datetime.datetime(2012, 11, 20, 7, 57, 15, 901000, tzinfo=) >>> localize(localtime(row.modified)) u'Nov. 20, 2012, 8:57 a.m.' – Edke Nov 21 '12 at 09:33
  • 1
    @Edke Solution with defining property like method is POOR and is kind of BAD design pattern. Have a look at my solution/configuration. – andilabs Mar 21 '14 at 20:18

1 Answers1

9

The answer to you question is proper configuration of settings and formats in Django project. Structure of example project:

.
|-- README.md
|-- demo.db
|-- demo_time_set
|   |-- __init__.py
|   |-- demo.db
|   |-- formats
|   |   |-- __init__.py
|   |   `-- en
|   |       |-- __init__.py
|   |       `-- formats.py
|   |-- settings.py
|   |-- urls.py
|   `-- wsgi.py
|-- manage.py
|-- requirments.txt
`-- some_app
    |-- __init__.py
    |-- admin.py
    `-- models.py

You can define it for multiple languages just by providing directory with appropriate name and formats.py inside. The example content of formats.py where all the MAGIC happens can look as follows:

# HERE FORMATING AS shown in:
# LIST: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
DATE_FORMAT = 'd-m-Y'
TIME_FORMAT = 'H:i'
DATETIME_FORMAT = 'd-m-Y H:i'
YEAR_MONTH_FORMAT = 'F Y'
MONTH_DAY_FORMAT = 'F j'
SHORT_DATE_FORMAT = 'm/d/Y'
SHORT_DATETIME_FORMAT = 'm/d/Y P'
FIRST_DAY_OF_WEEK = 1

# BUT here use the Python strftime format syntax,
# LIST: http://docs.python.org/library/datetime.html#strftime-strptime-behavior

DATE_INPUT_FORMATS = (
    '%d-%m-%Y',     # '21-03-2014'
)
TIME_INPUT_FORMATS = (
    '%H:%M:%S',     # '17:59:59'
    '%H:%M',        # '17:59'
)
DATETIME_INPUT_FORMATS = (
    '%d-%m-%Y %H:%M',     # '21-03-2014 17:59'
)

DECIMAL_SEPARATOR = u'.'
THOUSAND_SEPARATOR = u','
NUMBER_GROUPING = 3

Please notice two links in the comments, which will guide you to lists of proper configurations, which ARE DIFFERENT for DIFFERENT parts!

In your settings.py just add:

FORMAT_MODULE_PATH = 'demo_time_set.formats'

[GITHUB] Here is a full working example: https://github.com/andilab/demo_time_set

andilabs
  • 22,159
  • 14
  • 114
  • 151
  • Say I want to *store* the dates in UTC but display them in local time? I have my time zone set to `UTC` and my locale to `en` but it's not taking into account the formats defined in `myapp/formats/en/formats.py`... Something missing? – tutuca Jun 10 '14 at 21:21
  • 1
    @tutuca please read it: https://docs.djangoproject.com/en/1.6/topics/i18n/timezones/#time-zone-aware-output-in-templates – andilabs Jun 10 '14 at 21:28
  • 1
    FYI this is still valid on django 1.8 – Luis Palacios Feb 03 '16 at 22:42
  • 5
    This doesn't do what was asked. What was asked is how to display and get input with time from the local time zone in Django admin, while keeping the internal system using UTC. This doesn't accomplish that goal. -1 – Greg Schmit Oct 03 '18 at 23:43