본문 바로가기
Django/Django Rest Framework

12. Django DRF 외래 키

by S.T.Lee 2022. 6. 19.

외래 키 종류

  • ForeignKey : many-to-one 형태로 특정 테이블에서 다른 테이블을 참조 할 수 있다,
    • 영화관과 시청자의 관계를 나타 낼 때, 시청자 테이블에서 영화관 테이블을 Foreign Key를 사용해 관계를 맺을 수 있다.
  • OneToOneField : one-to-one 형태로 ForeignKey와 동일하지만, 1:1 관계만 가능하다.
    • 사용자 계정 테이블과 사용자 프로필 테이블이 별도로 존재 할 때, 계정 테이블을 프로필에서 1:1로 관계를 맺을 수 있다.
    • ForeginKey(unique=True)로 설정해주는거랑 같다.
  • ManyToManyField : many-to-many 형태로 한 개의 필드에서 여러개의 테이블을 참조 할 수 있다.
    • 영화라는 테이블에서 카테고리 테이블의 object를 참조하고 싶을 때, many to many 관계를 사용해 2개 이상의 object를 참조할 수 있다.
    • Many-to-many 관계로 생성 된 필드는 db에 값이 2개 이상 저장되는 것이 아닌, 중간 테이블이 생성된다.

 

모델 필드에 따른 DB 저장 방식

from ntpath import join
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser

# Create your models here.
class UserManager(BaseUserManager):
    def create_user(self, username, password=None):
        if not username:
            raise ValueError('Users must have an username')
        user = self.model(
            username=username,
        )
        user.set_password(password)
        user.save(using=self._db)
        return user
    
    def create_superuser(self, username, password=None):
        user = self.create_user(
            username=username,
            password=password
        )
        user.is_admin = True
        user.save(using=self._db)
        return user


class User(AbstractBaseUser):
    username = models.CharField("사용자 계정", max_length=50, unique=True)
    password = models.CharField("비밀번호", max_length=200)
    email = models.EmailField("이메일 주소", max_length=100)
    fullname = models.CharField("이름", max_length=20)
    join_date = models.DateField("가입일", auto_now_add=True)
    
    is_active = models.BooleanField(default=True)
    
    is_admin = models.BooleanField(default=False)
    
    USERNAME_FIELD = 'username'
    
    REQUIRED_FIELDS = []
    
    objects = UserManager()
    
    def __str__(self):
        return f"{self.username} / {self.email} / {self.fullname}"
    
    #권한 설정 #손 건들일이 없다
    def has_perm(self, perm, obj=None):
        return True
    #손 건들일이 없다
    def has_module_perms(self, app_label):
        return True
    
    @property
    def is_staff(self):
        return self.is_admin


class UserProfile(models.Model):
    user = models.OneToOneField(to=User, verbose_name="사용자", on_delete=models.CASCADE, primary_key=True)
    hobby = models.ManyToManyField("Hobby", verbose_name="취미")
    introduction = models.TextField("소개")
    birthday = models.DateField("생일")
    age = models.IntegerField("나이")
    
    def __str__(self):
        return f"{self.user.username} 님의 프로필"


class Hobby(models.Model):
    name = models.CharField("취미", max_length=50)
    
    def __str__(self):
        return self.name

분명 UserProfile에 hobby를 만들었는데 hobby가 없는것을 볼 수 있다. 그 이유는 외래 키에 2개 이상의 id값이 들어갈 수 없어서 DB자체적으로 중간 테이블을 만들기 때문이다. 위에서 userprofile_hobby라는 만들지 않은 테이블이 생성된것을 볼 수 있다.

상단과 같이 userprofile과 hobby가 값으로 있는 중간 테이블 구조를 볼 수 있다.

'Django > Django Rest Framework' 카테고리의 다른 글

14. Django DRF dir  (0) 2022.06.19
13. Django DRF 역참조  (0) 2022.06.19
11. Django DRF 로그아웃 구현  (0) 2022.06.19
10. Django DRF 로그인 구현  (0) 2022.06.19
9. Django DRF custom user 생성  (0) 2022.06.19