답변:
업데이트 :self._state
개인 인스턴스 변수가 아니지만 충돌을 피하기 위해 이름이 지정된 설명을 사용하면 확인 self._state.adding
하는 것이 선호되는 방법입니다.
self.pk is None:
객체가로 설정 UUIDField
되어 있지 않으면 새 Model 객체 내에서 True를 반환 합니다 primary_key
.
걱정해야 할 가장 중요한 경우는 ID 이외의 필드에 고유 제약 조건이 있는지 여부입니다 (예 : 다른 필드의 보조 고유 인덱스). 이 경우 여전히 새 레코드를 보유 할 수는 있지만 저장할 수는 없습니다.
is not
때보다는 사용해야 합니다!=
None
models.OneToOneField(OtherModel, primary_key=True)
입니다. 나는 당신이 사용해야한다고 생각합니다self.pk
UUIDField
기본 키로 사용하는 경우 self.pk
never None
입니다.
모델을 self.pk
확인할 수있는 대체 방법self._state
self._state.adding is True
창조
self._state.adding is False
업데이트
이 페이지 에서 얻었습니다
self._state.adding
작동 방식 에 대한 모든 세부 사항에 대해서는 확실하지 않지만 github.com/django/django/blob/stable/1.10.x/django/db/models/를 호출 한 후False
확인하면 항상 동일한 것 같습니다 . …super(TheModel, self).save(*args, **kwargs)
_state
비공개가 아닙니다. 처럼 _meta
필드 이름과 혼동을 피하기 위해 밑줄이 붙습니다. (링크 된 문서에서 어떻게 사용되는지에 주목하십시오.)
is_new = self._state.adding
후, super(MyModel, self).save(*args, **kwargs)
다음if is_new: my_custom_logic()
검사 self.id
는 이것이 id
모델의 기본 키 라고 가정합니다 . 보다 일반적인 방법은 pk 단축키 를 사용하는 것 입니다.
is_new = self.pk is None
super(...).save()
.
에 대한 검사 self.pk == None
입니다 하지 개체를 삽입하거나 데이터베이스에 업데이트 될 것입니다 있는지 확인하기에 충분.
Django O / RM에는 기본적으로 PK 위치에 무언가가 있는지 확인하고 UPDATE가있는 경우 INSERT를 수행하는 특히 불쾌한 해킹이 있습니다 (PK가 None 인 경우 INSERT에 최적화 됨).
이 작업을 수행해야하는 이유는 개체를 만들 때 PK를 설정할 수 있기 때문입니다. 기본 키의 시퀀스 열이있는 경우 일반적이지 않지만 다른 유형의 기본 키 필드에는 적용되지 않습니다.
정말로 알고 싶다면 O / RM의 기능을 수행하고 데이터베이스를 살펴 봐야합니다.
물론 코드에 특정 사례 self.pk == None
가 있으며 알아야 할 모든 것을 알려주는 가능성이 높지만 일반적인 해결책 은 아닙니다 .
UUIDField
기본 키로 사용하는 경우에 특히 그렇습니다 . 키는 DB 수준에서 채워지지 않으므로 self.pk
항상 True
입니다.
"만들어진"크워 그를 보내는 post_save 신호에 연결할 수 있습니다. 참이면 개체가 삽입 된 것입니다.
http://docs.djangoproject.com/en/stable/ref/signals/#post-save
ATOMIC_REQUESTS
하고 있으므로 기본값에 대해 잘 모르겠습니다.
self.id
및 force_insert
플래그를 확인하십시오 .
if not self.pk or kwargs.get('force_insert', False):
self.created = True
# call save method.
super(self.__class__, self).save(*args, **kwargs)
#Do all your post save actions in the if block.
if getattr(self, 'created', False):
# So something
# Do something else
새로 만든 객체 (자체)에 pk
가치 가 있기 때문에 편리 합니다.
UUIDField
기본 키 를 가지고 있어도 작동하는 솔루션의 경우 (다른 사람이 무시한None
경우 가 아니라 save
) 장고의 post_save 신호에 연결할 수 있습니다 . 당신이 추가 models.py :
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=MyModel)
def mymodel_saved(sender, instance, created, **kwargs):
if created:
# do extra work on your instance, e.g.
# instance.generate_avatar()
# instance.send_email_notification()
pass
이 콜백은 save
메소드 를 차단 하므로 양식을 사용하든 AJAX 호출에 Django REST 프레임 워크를 사용하든 응답을 유선으로 다시 보내기 전에 트리거 알림과 같은 작업을 수행하거나 모델을 추가로 업데이트 할 수 있습니다. 물론 사용자를 기다리지 않고 책임감있게 사용하고 무거운 작업을 작업 대기열로 오프로드하십시오. :)
대신 id 대신 pk 를 사용하십시오 .
if not self.pk:
do_something()
위의 모든 시나리오에서 작동합니까?
if self.pk is not None and <ModelName>.objects.filter(pk=self.pk).exists():
...
> def save_model(self, request, obj, form, change):
> if form.instance._state.adding:
> form.instance.author = request.user
> super().save_model(request, obj, form, change)
> else:
> obj.updated_by = request.user.username
>
> super().save_model(request, obj, form, change)
UUIDField pk