[0208 일지]
- 지난시간에 작성했던 Melon 모델 작성
- Django document - Meta option 부터 시작
null과 빈 문자열
CharField
되도록 null 설정은 피하자 ->blank = True
설정- 닉네임과 같이 중복되는 데이터가 있으면 안되는 경우,
unique = True
,blank = True
설정하면 안된다.
왜냐하면 빈문자열도 unique로 인식하기 때문에 문제가 된다. -> 이럴땐null = True
로 설정해서,null
값이 들어가게 설정!
many to many 삭제
- ForeignKey처럼 CASCADE 이런 설정이 없음.
- many to many 의 경우, 속성을 삭제하면 관련된 요소가 함께 삭제된다.
- 하나가 삭제되면 관계에 있어서 별 의미가 없음
Model attributes
objects
- 장고는 디폴드로 objects 라는 Manager 객체를 자동으로 추가한다.
- 이 Manager 을 통해 쿼리작업을 진행 할 수 있다.
- 클래스에서만 접근이 가능하다!
- 주요 메소드
참고자료
- all() :테이블 데이터 전부 가져온다
- get() :하나의 row만 가져온다
- filter(): 특정 조건에 맞는 row를 가져온다
- distinct(): 중복된 값은 하라노만 표시하기 위해서 사용. SQL SELECT DISTINCT와 같은 효과
- frist()/last(): 데이터의 첫번째 row 출력 / 마지막 row 출력
Overridden model methods on bluck operations
- 많은 데이터를 한번에 create / update / dleate 실행시키면, 사용자가 재정의한 함수는 동작하지 않는다. 왜냐하면 데이터베이스 차원에서 데이터를 처리하기 따로 재정의한 동작은 일어나지 않는다.
- 사용자 정의 함수의 경우, pre_delete / post_delete delete동작에는 시그널 쓰는거 권장.
추상 기본 클래스
from django.db import models
# Create your models here.
class CommonInfo(models.Model):
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
class Meta:
abstract = True
class Student(CommonInfo):
home_group = models.CharField(max_length=5)
-
abstract = True
설정
모델 클래스로 존재는 하지만, 테이블로는 존재하지 않는다.
자식이 이것을 상속해서 사용 -
이 경우,
CommonInfo
는 추상클래스이기 때문에, 인스턴스 생성이 불가능하다. 그러나CommonInfo
를 상속받은Student
를 이용하면 된다. -
부모의
Meta
클래스도 상속 받을 수 있다. 또한abstract
의 속성은 상속에 포함되어 있지 않기 때문에, 하위 클래스에서 상속이 필요하면 다시Meta
클래스에 지정해줘야 한다. -
상위
Meta
클래스에db_table
(테이블 이름 설정)을 넣지 말것. 하위 클래스의 모든 이름들이 동일한 오류가 생길 수 있다.
related_name 과 related_query_name
ForeignKey 혹은 ManyToMany 관계의 경우, 역참조를 사용할 때
related_name 과 related_query_name 을 지정해줘야 한다.
상속 클래스에서 자주 발생되는 문제로, 같은 상위 클래스를 상속 받는 경우 오류가 생긴다.
from django.db import models
# Create your models here.
class Person(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Item(models.Model):
person = models.ForeignKey(
Person,
on_delete=models.CASCADE,
# 같은 이름을 설정해놓은 상황
related_name='items',
related_query_name='item',
)
class Meta:
abstract = True
class Fruit(Item):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Food(Item):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
<!--오류 내용 -->
$django git:(master*)./manage.py makemigrations
SystemCheckError: System check identified some issues:
ERRORS:
rel.Food.person: (fields.E304) Reverse accessor for 'Food.person' clashes with reverse accessor for 'Fruit.person'.
HINT: Add or change a related_name argument to the definition for 'Food.person' or 'Fruit.person'.
rel.Fruit.person: (fields.E304) Reverse accessor for 'Fruit.person' clashes with reverse accessor for 'Food.person'.
HINT: Add or change a related_name argument to the definition for 'Fruit.person' or 'Food.person'.
class Item(models.Model):
person = models.ForeignKey(
Person,
on_delete=models.CASCADE,
# case1
# 이 경우, 오류는 나지 않지만 query_name을 역참조 했을 경우,
# 상속을 가장 최근에 받는 클래스하고만 연결 (Food class만 인식)
# related_name='%(app_label)s_%(class)ss',
# related_query_name='item',
# 올바른 표기법
related_name = '%(app_label)s_%(class)ss'
related_query_name = '%(app_label)s_%(class)s'
)
- %(app_label)s : 각 앱의 이름은 중복이 없어야 하며, 앱 내의 모델 클래스 이름도 중복이 없어야, 이름이 결과적으로 달라진다.
- %(class)s : 사용되는 하위 클래스의 이름(ex- rel_food__name__)
오류
상대 경로로 저장하기
from foreign.models import car
# 상대 경로로 지정하기!! 이동할때 오류가 안생김
from .models import car