Для работы со временем в моделях Django есть несколько полей. Одно из применений таких полей - это создание меток (timestamp), которые указывают либо на дату созданию строки в базе либо на дату ее изменения.
В Django предусмотрено два параметра, которые могут сделать это:
- auto_now- обновляет метку каждый раз при изменении (сохранении) строки в базе;
- auto_now_add- создает метку при создании строки в базе.
Эти параметры можно указать в двух полях, которые указываются при создании модели:
- DateField - хранит только дату;
- DateTimeField - хранит дату и время;
- TimeField - хранит только время.
В файле модели приложения models.py мы можем создать эти поля так:
from django.db import models
class TestModel(models.Model):
title = models.CharField(max_length=120)
# Создаст дату при каждом сохранении объекта
date1 = models.DateField(auto_now=True)
# Создаст дату при создании объекта
date2 = models.DateField(auto_now_add=True)
# Создаст дату и время при изменении объекта
date3 = models.DateTimeField(auto_now=True)
# Создаст дату и время при создании объекта
date4 = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
Одна из особенностей полей, где указаны параметры auto_now или auto_now_add в том, что они становятся неизменяемыми для вас (readonly). Из-за этого, в примере выше, создается единственное поле title, которое можно редактировать. При каждом создании и редактировании title у нас будет создаваться или изменяться и время.
Из-за причин описанных выше мы сможем вывести их в админке используя только 'readonly_fields' или 'list_display':
from django.contrib import admin
from .models import TestModel
@admin.register(TestModel)
class TestAdmin(admin.ModelAdmin):
readonly_fields = ('date1', 'date2', 'date3', 'date4')
Создание прямой ссылки в Django с get_absolute_url
Если в файле admin.py указать эти поля в fields, то получим ошибку:
- 'date1' cannot be specified for TestModel model form as it is a non-editable field.
Есть два способа изменить эти поля не меняя файлы фреймворка. Первый - это написать SQL в самой базе или через курсор в Django:
from django.db import connection
from app.models import TestModel
cursor = connection.cursor()
cursor.execute("UPDATE app_testmodel SET date1='2020-12-12' WHERE id=1")
TestModel.objects.get(id=1).date1
Второй способ - этой использование метода update, который есть у объектов. Это можно сделать т.к. эти поля автоматически срабатывают на метод save(), а не update():
TestModel.objects.filter(id=1).update(date1='2020-11-11')
...