수색…


매개 변수

클래스 / 메서드 그 이유
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)


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow