반복하지 말 것(DRY, Don't Repeat Yourself)
고유한 개념 및 데이터는 단 한 번, 단 한 곳에 존재하는 것으로 족합니다. 중복성은 나쁜 것이고, 정규화는 좋은 것입니다.
그러한 이유로, 본 프레임워크는 최소한의 것들을 가지고 최대한의 것을 만들어내도록 합니다.
Django는 Dry원칙을 따릅니다. 이 Dry원칙을 지키는 일부분으로 Custom Mnager클래스를 사용해보려 합니다.
Manager 클래스란 무엇일까?!
Django.db.models 에 존재하는 Manager 클래스입니다.
우리가 Django에서 흔히 사용했던 클래스.objects.create()의 objects를 의미합니다.
Django의 모델들은 objects라고 하는 default 매니저 클래스를 보유하게 됩니다.
Manager클래스를 커스텀하면 사용할 수 있는것들
- 매니저 클래스이름을 바꿀 수 있다.
- User.objects.create() 를 User.a.create()로 사용가능합니다. - 메서드 override를 통하여 메서드를 변경하거나 새로운 메서드를 만들 수 있다.
- 반환되는 query_set을 바꿀 수 있다.
기본 Manager클래스 호출 명 바꿔보기
from django.db import models
class User(models.Model):
name = models.CharField(max_length = 20)
a = models.Manager()
위와 같은 코드를 작성하게되면 아래와 같은 ORM이 사용가능하게됩니다.
User.a.get(id=1)
이를 다시한번 생각해본다면 장고의 Model클래스는 기본값으로 objects라는 변수에 models.Manager()가 있다는것을 알 수있습니다.
아래와같이 말이죠
from django.db import models
class User(models.Model):
name = models.CharField(max_length = 20)
objects = models.Manager()
Manager 클래스 여러개 사용해보기
Django에서는 아래와같이 여러개의 Manager클래스가 사용가능합니다.
from django.db import models
class User(models.Model):
name = models.CharField(max_length = 20)
objects = models.Manager() #default Manager Class
a = models.Manager()
User.objects.get(id=1)
User.a.get(id=1)
위의 두 코드는 같은 값을 반환하게됩니다. 하지만 이렇게 똑같은 매니저를 두개사용할 이유는 없을 것 입니다.
** Django는 모델클래스에 정의된 가장 처음의 Manager클래스를 default Manager클래스로 지정합니다.
Custom Manager 클래스 만들어보기
우선적으로 저는 많은 문서에서 사용하는 author와 book의 관계의 모델을 사용할 것 입니다.
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=20, unique=True)
class Book(models.Model):
name = models.CharField(max_length=20, unique=True)
author = models.ForeignKey('User', on_delete=models.CASCADE)
이제 Custom Manager 클래스를 만들어 보겠습니다.
Custom Manager 클래스를 만들기위해서는 django.db.models.Manager 클래스를 상속받아야 합니다.
from django.db import models
class BookManager(models.Manager): # 클래스 상속
def get_from_author(self,id, author_id):
book_row = self.get(id=id)
if book_row.author_id != author_id:
raise
return book_row
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=20, unique=True)
class Book(models.Model):
name = models.CharField(max_length=20, unique=True)
author = models.ForeignKey('User', on_delete=models.CASCADE)
objects = BookManager()
get_from_author라는 메서드는 book의 id와 autho_id를 받아 해당 책이 author의 것이 아니면 예외를 발생시키고
해당 author의 것이라면 해당 object를 반환시키는 메서드 이며 이를 Book모델의 objects로 할당하였습니다.
그렇다면 get_from_author를 제외한 다른메서드는 사용이 불가능한것일까요?
아닙니다. 상속을받았기때문에 기본적인 메서드들은 다 사용가능합니다.
Custom Manager 클래스에서 기본 메서드 override하여 사용하기
이번에는 get_from_author를 그냥 get메서드에 override하여 사용해보겠습니다.
from django.db import models
class BookManager(models.Manager): # 클래스 상속
def get(self,id, author_id):
book_row = self.get(id=id) # (1)
if book_row.author_id != author_id:
raise
return book_row
사실 위의 코드는 문제가 발생합니다.
override하였기때문에 (1)번의 코드에서 자기자신을 계속 부르게되며 최대재귀 오류를 내뱉게 됩니다.
이때는 self가 아닌 super()를 호출하여 사용합니다.
아래와 같이 말이죠
from django.db import models
class BookManager(models.Manager): # 클래스 상속
def get(self,id, author_id):
book_row = super().get(id=id) # (1)
if book_row.author_id != author_id:
raise
return book_row
커스텀 매니저 클래스내의 메서드중 기본메서드를 호출하는경우 위와 같이 super메서드를 사용하는것이 바람직합니다.
기존에 기본메서드에 override를 하지않았을지라도 나중에 변경될 가능성이 있기때문이죠
'Python > Django' 카테고리의 다른 글
[Django] 장고에서 TIME_ZONE & USE_TZ 파헤치기 (0) | 2023.01.06 |
---|---|
[Django]장고에서 앱이름 변경하기 (0) | 2022.11.26 |
[Django] Models class Manager (0) | 2022.06.26 |
[Django] ver.3 피드백 모음 (0) | 2022.06.19 |
[Django] Westagram 회원가입 기능 작성해보기 ver.3 (0) | 2022.06.13 |