Django
신호
수색…
매개 변수
클래스 / 메서드 | 그 이유 |
---|---|
UserProfile () 클래스 | UserProfile 클래스는 Django 기본 사용자 모델을 확장합니다. |
create_profile () 메소드 | create_profile () 메소드는 Django User 모델 post_save 신호가 해제 될 때마다 실행됩니다. |
비고
자, 세부 사항.
Django 신호는 특정 작업 (예 : 사전 저장 또는 사후 저장 또는 삭제)과 같은 작업을 앱에 알리는 방법입니다.
이 신호를 통해 신호가 방출되는 즉시 원하는 동작을 수행 할 수 있습니다.
예를 들어, 언제 새로운 장고 사용자는 모델과 같은 관련 PARAMS의 신호, 출시 사용자 생성 sender=User
특별히이 경우에 발생하는 특정 활동에 신호의 청취를 대상으로 할 수 있도록, 새로운 사용자 생성을 .
위의 예에서 User 객체가 생성 된 직후에 UserProfile 객체가 생성됩니다. 따라서 User
모델 (기본 Django 사용자 모델)의 post_save
신호를 post_save
듣고 새 User
를 만든 직후에 UserProfile
객체를 만듭니다.
Django Documentation은 가능한 모든 가능한 신호 에 대한 광범위한 문서를 제공 합니다 .
그러나 위의 예는 신호를 사용하는 것이 유용한 추가 기능 일 수있는 일반적인 사용 사례를 실제적으로 설명하는 것입니다.
"큰 힘에는 큰 책임이 따른다". 그들이 굉장하기 때문에 전체 앱이나 프로젝트에 신호가 흩어지면 유혹을받을 수 있습니다. 글쎄, 하지마. 그들이 차갑기 때문에 마음에 오는 모든 간단한 상황에 대한 해결책이 될 수는 없습니다.
신호는 늘 그렇듯 모든 것이 아닙니다. 로그인 / 로그 아웃, 신호가 훌륭합니다. 사용자 모델과 같은 징후를 공개하는 주요 모델.
앱의 각 모델마다 신호를 생성하는 것은 어느 시점에서 압도적 인 결과를 가져올 수 있으며 Django 신호의 스파링 사용에 대한 전반적인 아이디어를 무효화 할 수 있습니다.
Django 책 두 권을 기반으로 할 때 신호를 사용하지 마십시오 .
- 신호는 하나의 특정 모델과 관련되며
save()
의해 호출 될save()
있는 모델의 메서드 중 하나로 이동할 수 있습니다. - 신호는 커스텀 모델 매니저 방식으로 대체 될 수 있습니다.
- 신호는 특정 뷰와 관련되어 있으며 해당 뷰로 이동할 수 있습니다.
다음과 같은 경우 신호를 사용하는 것이 좋습니다.
- 신호 수신기는 하나 이상의 모델을 변경해야합니다.
- 여러 개의 앱에서 동일한 신호를 보내고 동일한 수신자가 동일한 방식으로 처리하도록하려고합니다.
- 모델 저장 후 캐시를 무효화하려고합니다.
- 콜백이 필요한 이상한 시나리오가 있으며 신호를 사용하는 것 외에 다른 방법으로 처리 할 수 없습니다. 예를 들어 타사 앱 모델의
save()
또는init()
을 기반으로 무언가를 트리거하려고합니다. 타사 코드를 수정할 수 없으며 확장이 불가능할 수 있으므로 신호가 콜백에 대한 트리거를 제공합니다.
사용자 프로필 확장 예제
이 예제는 장고 사용자 프로필 확장 에서 가져온 스 니펫입니다.
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='user')
website = models.URLField(default='', blank=True)
bio = models.TextField(default='', blank=True)
def create_profile(sender, **kwargs):
user = kwargs["instance"]
if kwargs["created"]:
user_profile = UserProfile(user=user)
user_profile.save()
post_save.connect(create_profile, sender=User)
신호를 게시 / 프리하는 다른 구문
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='user')
website = models.URLField(default='', blank=True)
bio = models.TextField(default='', blank=True)
@receiver(post_save, sender=UserProfile)
def post_save_user(sender, **kwargs):
user = kwargs.get('instance')
if kwargs.get('created'):
...
pre_save 신호에서 삽입 또는 업데이트인지 찾는 방법
pre_save
를 사용하여 데이터베이스의 save
작업이 기존 개체를 업데이트하거나 새 개체를 만드는 작업인지 여부를 확인할 수 있습니다.
이를 달성하기 위해 모델 객체의 상태를 확인할 수 있습니다.
@receiver(pre_save, sender=User)
def pre_save_user(sender, instance, **kwargs):
if not instance._state.adding:
print ('this is an update')
else:
print ('this is an insert')
이제 save
작업이 발생할 때마다 pre_save
신호가 실행되고 인쇄됩니다.
-
this is an update
액션에서 파생 된 액션 인 경우 업데이트입니다. -
this is an insert
동작에서 파생 된 동작 인 경우 삽입입니다.
이 메서드는 추가 데이터베이스 쿼리가 필요하지 않습니다.
확장 모델에 대한 상속 신호
Django의 신호는 등록시 정확한 클래스 서명으로 제한되므로 서브 클래 싱 된 모델은 동일한 신호에 즉시 등록되지 않습니다.
이 모델을 가지고 예를 들어 신호
class Event(models.Model):
user = models.ForeignKey(User)
class StatusChange(Event):
...
class Comment(Event):
...
def send_activity_notification(sender, instance: Event, raw: bool, **kwargs):
"""
Fire a notification upon saving an event
"""
if not raw:
msg_factory = MessageFactory(instance.id)
msg_factory.on_activity(str(instance))
post_save.connect(send_activity_notification, Event)
확장 된 모델을 사용하면 신호를 각 하위 클래스에 직접 첨부해야합니다. 그렇지 않으면 영향을 미치지 않습니다.
post_save.connect(send_activity_notification, StatusChange)
post_save.connect(send_activity_notification, Comment)
Python 3.6을 사용하면 몇 가지 추가 클래스 메소드를 활용하여이 바인딩을 자동화하는 클래스를 빌드 할 수 있습니다.
class Event(models.Model):
@classmethod
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
post_save.connect(send_activity_notification, cls)