FrameWork/Django
App Models
mansoorrr
2024. 7. 12. 09:12
Application(app)의 models.py에 작성한다. app에서 관리할 데이터를 정의하는 곳으로 database와 소통한다.
결국 데이터베이스에서 사용할 table을 만드는 곳이다. 쿼리문을 적을필요 없이 클래스로 만들면 db의 테이블로 만들어진다. 필드명, 필드타입, 유니크, nullable 등을 세팅한다.
- 모델생성(클래스) > 모델적용(makemigrations > migrate) 순으로 진행
[model 생성]
- app의 model.py에 들어가면 django에서 미리 임포트 해놨다(from django.db import models)
- import한 model을 상속받아 클래스를 만듬
- 필드타입을 디테일하게 설명할 수록 장고와 데이터베이스가 잘 소통하게 됨
- 모델을 만들때 관행적으로 모델에 대한 설명을 적음
class House(models.Model):
''' 모델에 대한 설명 '''
name = models.CharField(max_length=140) # 집의 이름
price = models.PositiveIntegerField() # 일박 가격
description = models.TextField() # 집의 설명
address = models.CharField(max_length=140) #집의 주소
번호 | 필드명 | 사용하는 이유 | 비고 |
1 | CharFiled | 길이가 있는 텍스트 | max_length= |
2 | IntegerField | 정수 | |
3 | PositiveIntegerField | 양수인 정수 | |
4 | TextField | 길이가 긴 텍스트 |
[모델적용]
- 모델을 만들고 저장을 한 후 db를 살펴보면 생성한 모델이 보이지 않음
- 데이터베이스에 적용하기 위해 migration이 필요
- cmd에 아래 명령어를 순서대로 입력
- python manage.py makemigrations
- model이 수정되었음을 알림
- makemigrations할때마다 파일이 생성됨
- python manage.py migrate
- db에 적용
- python manage.py makemigrations
[**상속과 커스텀**]
- 모델은 상속받아서 만들수도 있고 커스텀 할수도 있다.
- 만약 Django의 기본 모델을 상속받아서 커스텀 하고 싶다면 기본모델은 건들면 안됨
- 대신 필드를 덮어쓰는 방식으로 커스텀을 진행한다.
- 예시: Django에서 기본적으로 제공하는 AbstractUser를 상속받은 User라는 모델이 있다. User모델을 다음과 같이 커스텀 하고자 한다.
- first_name, last_name 필드는 사용하지 않으려고 한다.
- name(이름)이라는 필드를 새로 만들고자 한다.
- is_host(호스트여부)라는 필드를 새로 만들고자 한다.
class AbstractUser(AbstractBaseUser, PermissionsMixin):
username_validator = UnicodeUsernameValidator(...)
username = models.CharField(...)
first_name = models.CharField(_("first name"), max_length=150, blank=True)
last_name = models.CharField(_("last name"), max_length=150, blank=True)
email = models.EmailField(_("email address"), blank=True)
is_staff = models.BooleanField(...)
is_active = models.BooleanField(...)
date_joined = models.DateTimeField(_("date joined"), default=timezone.now)
objects = UserManager(...)
EMAIL_FIELD = "email"
USERNAME_FIELD = "username"
REQUIRED_FIELDS = ["email"]
class User(AbstratUser):
#사용안함으로 커스텀(editable=False)
first_name = models.CharField(max_length=150, editable=False)
last_name = models.CharField(max_length=150, editable=False)
#새롭게 사용할 필드
name = models.CharField(max_length=150, default="")
is_host = models.BooleanField(default=False)
- db를 수정, 커스텀 하면 makemigrations로 마이그레이션을 생성하고 migrate로 db에 적용한다.
- 만약 db에 데이터가 들어있는 상황인데 필드를 추가하게 되면 default를 설정해줘야 한다. default값을 설정 해주면 makemigraions > migrate가 정상 실행 됨
- non-nullable fileld의 경우(models.BooleanField): default=True or False
- nullable field의 경우: defualt="", 다른것들
- 기존의 데이터는 새로운 필드가 추가된 부분에 어떤게 채워져야 할지 모르기 때문이다.
[**relationship**]
- relationship은 RDBMS에서 테이블간 관계를 맺는 것을 의미한다.
- 관계 형성에는 몇가지가 있다.
- PK(Primary Key): Django에서는 테이블에 자동으로 id가 생기고 이 컬럼을 pk로 지정한다.
- FK(Foreign Key): 다른 테이블의 무슨 컬럼을 참조할 것인지 정한다.
- on_delete: 참조한 테이블의 데이터가 변경되거나 삭제되면 어떻게 할것인지를 정한다
- CASCADE: 참조한 테이블의 데이터가 삭제되면 본 테이블의 데이터도 삭제한다
- SET_NULL: 참조한 데이터가 삭제되면 본 테이블의 해당 컬럼은 NULL처리 한다
- on_delete: 참조한 테이블의 데이터가 변경되거나 삭제되면 어떻게 할것인지를 정한다
- ForeignKey지정
# users app의 User모델을 참조(자동으로 id를 참조하게 됨)
# on_delete=CASCADE 이므로 User모델에서 특정 id가 삭제되면 House모델의 ownser_id가 id인 데이터는 함께 삭제됨
class House(models.Model):
<생략...>
owner_id = models.ForeignKey('users.User', on_delete=models.CASCADE)
- ManyToMany
- Foriegn Key의 경우:
- User 1명 --- Room 여러개
- Room 1개 --- User 1명
- ManyToMany의 경우
- Room 1개 --- Amenity 여러개
- Amenity 1개 --- Room 여러개
- db에 새로운 테이블이 하나 생성됨
- related_name을 이용해 거꾸로 검색 가능
- Foriegn Key의 경우:
# ManyToMany 연결
'''
방 1개 --- 속성 여러개
속성 1개 --- 방 여러개
=> 방여러개 ---- 속성 여러개
'''
class Room(CommonModel):
name = models.CharField(max_length=100,)
owner = models.ForeignKey('users.User', on_delete=models.CASCADE,)
amenities = models.ManyToManyField('rooms.Amenity', related_name='rooms',) #Amenity.rooms로 Amenity별 room정보를 알 수 있음(backref)
class Amenity(CommonModel):
name = models.CharField(max_length=150,)
description = models.CharField(max_length=150, null=True, blank=True,)
[**choices**]
- 모델에서 필드를 설정할때 choices를 설정할 수 있다.
- choices는 필드가 몇가지의 선택지를 가질때 설정한다
- gender: 남자, 여자
- language: 한국어, 영어, 일본어, 중국어
- currency: 원, 달러, 엔
- grade: 초등학교, 중학교, 고등학교, 대학교
- 모델안에 클래스를 만들어 적용한다.
- 이후 admin.py에 적용해주면 됨
class User(AbstractUser):
#choice class
class GenderChoice(models.TextChoice):
'''
변수 = (db에 저장될 데이터, 관리자패널에서 보여질 데이터)
이렇게 세팅함
'''
MALE = ('male', 'Male')
FEMALE = ('female', 'Female')
#새로운 필드 정의
gender = models.CharField(max_length=10, choices=GenderChoice.choices) #choices 설정(클래스명.choices)
[**Meta**]
- 모델의 메타정의를 만들때 사용함
- 여러 parameter를 사용해 모델 조작 가능
- abstract: 추상클래스로만 사용, 해당 모델을 db에는 저장하지 않음
- verbose_name_plural: 관리자패널에서 보일 모델의 이름을 정의
class CommonModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True,) #auto_no_add: 생성된 시간만 자동입력
modified_at = models.DateTimeField(auto_now=True,) #auto_now: 수정될때마다 수정시간 자동입력
#Meta정의
class Meta:
absrtract = True #추상클래스로만 사용, db에 저장안함