장고 1.1.
나는 models.py에 이것을 가지고있다 :
class User(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
행을 업데이트하면 다음과 같은 결과가 나타납니다.
[Sun Nov 15 02:18:12 2009] [error] /home/ptarjan/projects/twitter-meme/django/db/backends/mysql/base.py:84: Warning: Column 'created' cannot be null
[Sun Nov 15 02:18:12 2009] [error] return self.cursor.execute(query, args)
내 데이터베이스의 관련 부분은 다음과 같습니다
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
이것이 우려의 원인입니까?
추가 질문 : 내 관리 도구에서이 두 필드가 표시되지 않습니다. 예상 되나요?
답변
auto_now
속성이 설정된 모든 필드 도 상속 editable=False
되므로 관리자 패널에 표시되지 않습니다. 과거에 auto_now
와 auto_now_add
인수를 없애는 것에 대한 이야기가 있었지만 여전히 존재하지만 사용자 정의 save()
방법 만 사용하는 것이 좋습니다 .
그래서, 내가 사용하지 않는 것이 좋습니다, 제대로이 작품을 만들기 위해 auto_now
또는 auto_now_add
대신 자신의 정의 save()
가 있는지 확인하는 방법을 created
경우에만 업데이트됩니다 id
(예 : 항목을 처음 만들 때와 같이) 설정되지 않은, 그리고 업데이트가 modified
항목마다 저장됩니다.
Django를 사용하여 작성한 다른 프로젝트와 똑같은 작업을 수행 했으므로 save()
다음과 같이 보일 것입니다.
from django.utils import timezone
class User(models.Model):
created = models.DateTimeField(editable=False)
modified = models.DateTimeField()
def save(self, *args, **kwargs):
''' On save, update timestamps '''
if not self.id:
self.created = timezone.now()
self.modified = timezone.now()
return super(User, self).save(*args, **kwargs)
도움이 되었기를 바랍니다!
의견에 대한 답변으로 수정 :
오버로드 save()
와 이러한 필드 인수에 의존하는 이유 는 두 가지입니다.
- 위에서 언급 한 기복은 신뢰성과 함께. 이러한 주장은 Django가 상호 작용하는 방법을 알고있는 각 유형의 데이터베이스가 날짜 / 시간 스탬프 필드를 처리하는 방식에 크게 의존하고 있으며 모든 릴리스간에 중단 및 / 또는 변경되는 것으로 보입니다. (내가 그것들을 모두 제거하라는 요구의 원동력이라고 믿는다).
- 그것들은 DateField, DateTimeField 및 TimeField에서만 작동하며이 기술을 사용하면 항목을 저장할 때마다 모든 필드 유형을 자동으로 채울 수 있습니다.
- 에 따라 TZ 인식 또는 순진한 개체를 반환하므로
django.utils.timezone.now()
vs.를 사용하십시오 .datetime.datetime.now()
datetime.datetime
settings.USE_TZ
OP가 오류를 보인 이유를 해결하기 위해 정확히 알지 못하지만 created
에도 불구하고 전혀 채워지지 않은 것처럼 보입니다 auto_now_add=True
. 나에게 그것은 버그로 눈에 띄는, 위 내 작은 목록의 항목 # 1을 강조 : auto_now
과 auto_now_add
최상의 색다른 있습니다.
답변
그러나 나는 대답에 표현 된 의견 이 다소 구식 이라고 지적하고 싶었습니다 . 더 최근의 토론 (장고 버그 # 7634 및 # 12785 )에 따르면 auto_now 및 auto_now_add는 아무데도 가고 있지 않으며 원래 토론으로 이동하더라도 커스텀 저장에서 RY에 대한 강력한 논쟁을 찾을 수 있습니다 행동 양식.
더 나은 솔루션이 제공되었지만 (맞춤형 필드 유형), 장고로 만들기에 충분한 운동량을 얻지 못했습니다. 세 줄로 직접 작성할 수 있습니다 ( Jacob Kaplan-Moss의 제안입니다 ).
from django.db import models
from django.utils import timezone
class AutoDateTimeField(models.DateTimeField):
def pre_save(self, model_instance, add):
return timezone.now()
#usage
created_at = models.DateField(default=timezone.now)
updated_at = models.AutoDateTimeField(default=timezone.now)
답변
부수적 인 질문에 대해 말하기 : 관리자에서이 필드를 보려면 (편집 할 수는 없지만) readonly_fields
관리자 클래스에 추가 할 수 있습니다 .
class SomeAdmin(ModelAdmin):
readonly_fields = ("created","modified",)
글쎄, 이것은 최신 장고 버전에만 적용됩니다 (1.3 이상)
답변
가장 쉬운 (아마도 가장 우아한) 솔루션 default
은 호출 가능으로 설정할 수 있다는 사실을 활용하는 것 입니다. 따라서 관리자의 auto_now 특수 처리를 피하려면 다음과 같이 필드를 선언하면됩니다.
from django.utils import timezone
date_filed = models.DateField(default=timezone.now)
timezone.now()
기본값이 업데이트 되지 않도록 사용하지 않는 것이 중요합니다 (즉, 코드가로드 될 때만 기본값이 설정 됨). 이 작업을 많이하면 사용자 정의 필드를 만들 수 있습니다. 그러나 이것은 이미 생각하기에 꽤 건조합니다.
답변
다음과 같이 모델 클래스를 변경하면 :
class MyModel(models.Model):
time = models.DateTimeField(auto_now_add=True)
time.editable = True
그러면이 필드가 관리자 변경 페이지에 나타납니다
답변
내가 읽은 내용과 지금까지 Django에 대한 내 경험에 따르면 auto_now_add는 버그가 있습니다. 나는 jthanism에 동의합니다 — 깨끗한 정상적인 저장 방법을 무시하고 무엇이 문제인지 알고 있습니다. 이제 건조시키기 위해 TimeStamped라는 추상 모델을 만듭니다.
from django.utils import timezone
class TimeStamped(models.Model):
creation_date = models.DateTimeField(editable=False)
last_modified = models.DateTimeField(editable=False)
def save(self, *args, **kwargs):
if not self.creation_date:
self.creation_date = timezone.now()
self.last_modified = timezone.now()
return super(TimeStamped, self).save(*args, **kwargs)
class Meta:
abstract = True
그런 다음이 타임 스탬프 동작을 가진 모델을 원할 때 서브 클래스 만 :
MyNewTimeStampyModel(TimeStamped):
field1 = ...
관리자에게 필드를 표시하려면 editable=False
옵션을 제거하십시오.
답변
이것이 우려의 원인입니까?
아니요, 장고는 모델을 저장하는 동안 자동으로 추가하므로 예상됩니다.
추가 질문 : 내 관리 도구에서이 두 필드가 표시되지 않습니다. 예상 되나요?
이 필드는 자동으로 추가되므로 표시되지 않습니다.
위의 내용에 덧붙여서, synack이 말했듯이, django 메일 링리스트에서 이것을 제거하기위한 토론이있었습니다. 왜냐하면 “잘 설계되지 않았고” “핵”이기 때문입니다
내 각 모델에서 사용자 정의 save ()를 작성하는 것은 auto_now를 사용하는 것보다 훨씬 고통입니다.
분명히 모든 모델에 쓸 필요는 없습니다. 한 모델에 쓰고 다른 모델을 상속 할 수 있습니다.
하지만, auto_add
하고 auto_now_add
있다, 나는 방법을 자신을 작성하는 것보다 오히려 그들을 사용할 수 있습니다.