Django에서는 로그인, 로그아웃이나 모델 생성등 어떤 기능을 작동할 때, singal을 발생 시킨다.
그래서 signal을 통해 기능을 추가할 수 있다. (회원가입 했을때 축하 메일을 보내는 것 처럼)
Django를 다룰 때 필수적인 기능인 signal에 대해서 정리해보려고 한다.
이번에 할 기능은 회원 가입시 개발 중인 Page에서 자동으로 관련 모델을 생성해주는 기능을 적어보려고 한다.
1. Signals.py
user_management/signals.py
from user.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from user_management.models import UserCourseRelationship, UserPyCoin
@receiver(post_save, sender=User)
def create_user_account(sender, instance, created, **kwargs):
if created:
UserCourseRelationship.objects.create(user=instance)
UserPyCoin.objects.create(user=instance)
회원 가입이 되었을 때, 자동으로 UserCourseRelationship 모델과 UserPyCoin 모델을 생성해주려고 한다.
먼저 나는 User 모델이 user.models에 AbstractUser로 재정의 되어 있으니 user.models.py에서 가져왔다.
그리고 django signals을 가져오면 되는데 회원가입, 즉 새로운 User 모델이 생성이 되는 것이므로 post_save(모델이 생성될 때 사용하는 signal)을 사용한다.
그리고 새로운 User 모델이 생성되었을 때(회원 가입 시), 기본 모델을 생성해주는 것이기 때문에 created를 사용한다. (created를 사용하기 위해 post_save로 해주었다고 생각하면 된다. created가 없으면 User모델이 동작할 때 마다 이벤트가 발생된다. 즉 로그인만 해도 자동으로 기본 모델이 생성되어 버린다.)
def create_user_account(sender, instance, created, **kwargs):
if created:
UserCourseRelationship.objects.create(user=instance)
UserPyCoin.objects.create(user=instance)
sender는 User 모델을 의미하고 instance에는 현재 만들어진 인스턴스(회원 가입이므로 방금 회원가입한 사람)가 저장된다. 정리하자면 sender는 모델 그 자체이고 instance는 방금 생성된 instance를 뜻한다.
2. apps.py에 작성
user_management/apps.py
class AccountConfig(AppConfig):
name = 'user_management'
def ready(self):
import user_management.signals
다음은 apps.py에 우리가 만든 signals.py를 등록해줘야한다. 여기서 name에는 signals.py가 있는 app이름을 적어야 한다.
SELECT * FROM web_article WHERE site_id=1 AND hit=0;
ORM
Article.objects.filter(site_id=1,hit=0)
OR
SQL
SELECT * FROM web_article WHERE site_id=1 OR hit=0;
ORM
from django.db.models import Q
Article.objects.filter(Q(site_id=1)|Q(hit=0))
LIKE '%s%'
SQL
SELECT * FROM web_article WHERE subject LIKE '%공무원%';
ORM
Article.objects.filter(subject__icontains='공무원')
LIKE 's%'
SQL
SELECT * FROM web_article WHERE SUBJECT LIKE '유승민%';
ORM
Article.objects.filter(subject__startswith='유승민')
LIKE '%s'
SQL
SELECT * FROM web_article WHERE SUBJECT LIKE '%의혹';
ORM
Article.objects.filter(subject__endswith='의혹')
>=
SQL
SELECT * FROM web_article WHERE hit >= 2;
ORM
Article.objects.filter(hit__gte=2)
<=
SQL
SELECT * FROM web_article WHERE hit <= 2;
ORM
Article.objects.filter(hit__lte=2)
>
SQL
SELECT * FROM web_article WHERE hit > 1;
ORM
Article.objects.filter(hit__gt=1)
<
SQL
SELECT * FROM web_article WHERE hit < 1;
ORM
Article.objects.filter(hit__lt=1)
LEFT JOIN(ManyToManyField)
SQL
SELECT b.id FROM web_article_category AS a LEFT JOIN web_article AS b ON a.article_id = b.id LEFT JOIN web_category AS c ON c.id=a.category_id WHERE c.name='정치';
ORM
Category.objects.get(name='정치').article_set.all()
INSERT
집어넣기
SQL
INSERT INTO web_site SET name='뉴스타파';
ORM
site = Site(name='뉴스타파')
site.save()#commit
있으면 가져오고 없으면 집어 넣기
SQL
INSERT INTO web_site SET name='한겨레';
ORM
site = Site.objects.get_or_create(name='한겨레')#save 메서드 호출 없이도 바로 입력됨
ForeignKey, ManyToManyField
SQL
INSERT INTO web_site SET name='PPSS';#id = 7
INSERT INTO web_article SET subject='뉴스제목', url='http://news.com/12345', date='2017-02-02 12:34:56', site_id=7;#id = 60
INSERT INTO web_category SET name='정치'; #id = 1
INSERT INTO web_category SET name='뉴스'; #id = 7
INSERT INTO web_article_category SET article_id=60, category_id=1;#category = 정치
INSERT INTO web_article_category SET article_id=60, category_id=7;#category = 뉴스
ORM
site, created = Site.objects.get_or_create(name='PPSS')