source

Django auto_now 및 auto_now_add

gigabyte 2022. 12. 28. 21:37
반응형

Django auto_now 및 auto_now_add

장고 1.1의 경우.

제 모델에는 이게 있어요.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,

이것이 우려의 원인입니까?

부수적인 질문: 관리 도구에서 두 개의 필드가 표시되지 않습니다.예상된 건가요?

속성이 설정된 필드도 상속됩니다.editable=False따라서 관리 패널에는 표시되지 않습니다.요.auto_now논쟁은 없어지고, 아직 존재하지만, 커스텀 방식을 사용하는 것이 좋다고 생각합니다.

이 기능을 저는 이 기능을 사용하지 않는 .auto_now ★★★★★★★★★★★★★★★★★」auto_now_add, 독자적인 「」를 정의합니다.save()「」를 .created는 업데이트 .id를 들어 아이템이되었을 때), 됩니다(업데이트 합니다).modified항목이 저장될 때마다 표시됩니다.

를 사용해서 , 선생님께서 쓰신 프로젝트도 마찬가지입니다. 그래서 당신의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() 필드 인수에 의존하는 두 즉, 두 가지입니다.

  1. 상기의 신뢰성에 관한 기복이 있습니다.이러한 인수는 Django가 날짜/시간 스탬프 필드를 처리하는 방법을 알고 있는 각 유형의 데이터베이스에 크게 의존하며, 모든 릴리스 간에 중단되거나 변경되는 것으로 보입니다.(이것이 그들을 완전히 제거하려는 요구의 이면에 있는 자극이라고 생각합니다.
  2. DateField, DateTimeField 및 TimeField에서만 작동하며 이 기술을 사용하면 항목이 저장될 때마다 모든 필드 유형을 자동으로 채울 수 있습니다.
  3. django.utils.timezone.now() ★★datetime.datetime.now() 순진한 TZ가 datetime.datetime 의거한 settings.USE_TZ.

한 이유에 는 알 수 , 「」라고 하는 것 .created이 전혀auto_now_add=True에 띄며, 위의 auto_now ★★★★★★★★★★★★★★★★★」auto_now_add잘해야 조각이 나죠.

그러나 나는 수용된 답변에 표현된 의견이 다소 구식이라는 것을 지적하고 싶었다.최근 논의된 내용에 따르면 (django bugs #7634 및 #12785),auto_now ★★★★★★★★★★★★★★★★★」auto_now_add님은 아무데도 가지 않습니다.원래의 논의에 가더라도 커스텀 세이브 방식에서는 (DRY와 같이) RY에 대한 강한 반론을 발견할 수 있습니다.

더 나은 솔루션(커스텀 필드 유형)이 제공되었지만, 이를 django로 만들기에 충분한 추진력을 얻지 못했습니다.당신은 당신의 것을 3행으로 쓸 수 있습니다(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 = AutoDateTimeField(default=timezone.now)

이 할 수 없습니다 "admin" 을 추가할 수 (「 」, 「 」readonly_fieldsadmin으로 이동합니다.

class SomeAdmin(ModelAdmin):
    readonly_fields = ("created","modified",)

음, 이것은 최신 버전의 장고에만 해당됩니다(1.3 이상이라고 생각합니다).

우아한)은 '어쩌면'을 '어쩌면'으로 설정할 수 합니다.default호출할 수 있습니다.대한 auto_now와 같이.

from django.utils import timezone
date_field = models.DateField(default=timezone.now)

이 말을 하지 않는 입니다.timezone.now()기본값은 업데이트되지 않습니다(즉, 코드가 로드된 경우에만 기본값이 설정됩니다).이 작업을 자주 수행하는 경우 사용자 정의 필드를 만들 수 있습니다.하지만, 이것은 이미 꽤 건조하다고 생각합니다.

모델 클래스를 다음과 같이 변경하는 경우:

class MyModel(models.Model):
    time = models.DateTimeField(auto_now_add=True)
    time.editable = True

그러면 이 필드가 관리자 변경 페이지에 표시됩니다.

class Feedback(models.Model):
   feedback = models.CharField(max_length=100)
   created = models.DateTimeField(auto_now_add=True)
   updated = models.DateTimeField(auto_now=True)

여기에서는 작성 시 및 다른 사용자가 피드백을 수정했을 때 타임스탬프가 표시되는 열을 만들고 업데이트했습니다.

auto_now_add는 인스턴스 작성 시간을 설정하는 반면 auto_now는 피드백을 변경한 시간을 설정합니다.

제가 읽은 내용과 지금까지의 장고 사용 경험에 따르면 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 = ...

admin으로 하려면 , 「admin」, 「admin」을 합니다.editable=False 표시

이것이 우려의 원인입니까?

아니요, 모델 저장 시 장고가 자동으로 추가되기 때문에 기대됩니다.

추가 질문: 관리 도구에서 이 두 개의 필드가 표시되지 않습니다.예상된 건가요?

이러한 필드는 자동으로 추가되므로 표시되지 않습니다.

위에 덧붙이자면, synack이 말했듯이, django 메일링 리스트는 "잘 설계되지 않았다"며 "해킹"이기 때문에 이를 삭제하기 위한 논란이 있었다.

각 모델에 커스텀 save()를 쓰는 것은 auto_now를 사용하는 것보다 훨씬 어렵습니다.

물론 모든 모델에 쓸 필요는 없습니다.하나의 모델에 쓰고 다른 모델을 상속할 수 있습니다.

만만...로서...auto_add ★★★★★★★★★★★★★★★★★」auto_now_add제가 직접 방법을 쓰느니 차라리 쓰겠습니다.

Admin 디스플레이에 대해서는, 다음의 회답을 참조해 주세요.

★★★★★★auto_now ★★★★★★★★★★★★★★★★★」auto_now_add로 설정되어 있다.editable=False디폴트로는 이것이 적용되는 이유입니다.

나는 오늘 직장에서 비슷한 것이 필요했다.은 " " " 입니다.timezone.now(), 클래스로부터 상속되는 관리 뷰에서는 편집 FormMixin 제 에 , , my my my my , , , , 。models.py다음 코드가 이러한 요건을 충족하였습니다.

from __future__ import unicode_literals
import datetime

from django.db import models
from django.utils.functional import lazy
from django.utils.timezone import localtime, now

def get_timezone_aware_now_date():
    return localtime(now()).date()

class TestDate(models.Model):
    created = models.DateField(default=lazy(
        get_timezone_aware_now_date, datetime.date)()
    )

★★★의 DateTimeField 「 」, 「 」를 삭제해 ..date()에서 변경하다)datetime.date로로 합니다.datetime.datetime 더 나은 ★★★★★★★★★ ★★★★timezone.datetimeDateTime ()만Date.

auto_now=TrueDjango 1.4.1에서는 동작하지 않았지만 아래 코드가 나를 구했다.이치노

from django.utils.timezone import get_current_timezone
from datetime import datetime

class EntryVote(models.Model):
    voted_on = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        self.voted_on = datetime.now().replace(tzinfo=get_current_timezone())
        super(EntryVote, self).save(*args, **kwargs)

하시면 됩니다.timezone.now() 및 성 created의 auto_now경경: :

from django.utils import timezone
class User(models.Model):
    created = models.DateTimeField(default=timezone.now())
    modified = models.DateTimeField(auto_now=True)

프라이머리 키가 auto- increment int,auto_now_add버그로 이어집니다.

다음은 Dango 기본 DateTimeField.pre_save 코드입니다.auto_now ★★★★★★★★★★★★★★★★★」auto_now_add:

def pre_save(self, model_instance, add):
    if self.auto_now or (self.auto_now_add and add):
        value = timezone.now()
        setattr(model_instance, self.attname, value)
        return value
    else:
        return super(DateTimeField, self).pre_save(model_instance, add)

인지 잘 .add하다

add = True if getattr(model_instance, 'id') else False

.id, (그래서)getattr(model_instance, 'id')는 False를 반환합니다.

다음은 South를 사용하고 있고 필드를 데이터베이스에 추가한 날짜를 기본값으로 설정하려는 경우의 대답입니다.

옵션 2를 선택한 후 datetime.datetime.now()를 선택합니다.

다음과 같습니다.

$ ./manage.py schemamigration myapp --auto
 ? The field 'User.created_date' does not have a default specified, yet is NOT NULL.
 ? Since you are adding this field, you MUST specify a default
 ? value to use for existing rows. Would you like to:
 ?  1. Quit now, and add a default to the field in models.py
 ?  2. Specify a one-off value to use for existing columns now
 ? Please select a choice: 2
 ? Please enter Python code for your one-off default value.
 ? The datetime module is available, so you can do e.g. datetime.date.today()
 >>> datetime.datetime.now()
 + Added field created_date on myapp.User

언급URL : https://stackoverflow.com/questions/1737017/django-auto-now-and-auto-now-add

반응형