일대일(1:1)관계
개체 A의 각 개체 인스턴스가 개체 B의 개체 인스턴스 하나와 관계를 맺을 수 있고, 개체 B의 각 개체 인스턴스도 개체 A의 개체 인스턴스 하나와 관계를 맺을 수 있는 관계
일대다(1:n)관계
개체 A의 각 개체 인스턴스는 개체 B의 개체 인스턴스 여러 개와 관계를 맺을 수 있지만, 개체 B의 각 개체 인스턴스는 개체 A의 개체 인스턴스 하나와만 관계를 맺을수 있는 관계
다대다(n:m)관계
개체 A의 각 개체 인스턴스가 개체 B의 개체 인스턴스 여러 개와 관계를 맺을 수 있고, 개체 B의 각 개체 인스턴스도 개체 A의 개체 인스턴스 여러 개와 관계를 맺을 수 있다면 두 개체는 다대다 관계.
다대다관계를 실제로 구현하기 위해선 각 테이블의 PrimaryKey를 외래키(FK)로 참조 하고 있는 연결테이블(매핑테이블)을 사용해야 한다.
날짜
date = models.DateField(..)
날짜와 시간을 같이
datetime = models.DateTimeField(...)
일반 문자를 받을 때 (최대길이 30자로 제한할 때)
integer = models.CharField(max_length=30)
글 쓰는 내용들 처럼 긴 텍스트를 받을 때
text = models.TextField(‘PLACEHOLDER’ …)
TextField를 사용하면 여러 줄 입력이 가능하다.
뉴스 헤드라인 처럼 콘텐츠의 주요 내용을 요약한 내용을 받을 때
slug = models.SlugField(‘SLUG’ …)
주소 받을 때
url = models.URLField(‘URL’ …)
이메일 받을 때
email = models.EmailField(‘mail’…)
숫자(정수) 받을 때
integer = models.IntegerField(‘number’…)
이미지 업로드 받을 때
image = models.ImageField(‘image’…)
파일 업로드 받을 때
file = models.FileField(‘File’…)
필드와 속성은 다양해서 여기에 굳이 따로 정리해두진 않겠다.
flat= True로 해두면 tuple형태가아닌 리스트형태로 받아올수있다.
3.META
1. db_table 이름 설정 기능
class Meta:
db_table = 'rating_conversions'
databases에서 show table; 를 했을때
| rating_conversions |
로 뜬다.
4.def str(self):
str은 파이썬 자체의 method로써,
str() 메서드는 모델 클래스의 객체의 문자열 표현을 리턴한다.
default 값은 모델명 object 이다.
admin 페이지에서 확인하면 테이블에 생성된 객체가 지정해놓은 값으로 표현된다.
한 모델 클래스 내부에서 동일한 클래스에 대해 여러번 외래키를 지정해줘야 할때는 related_name으로 구분을 지어 줘야한다.
그리고 참조해준 객체 입장에서 related_name을 설정해주는 것이 좋다.
class Comment(models.Model):
User = models.ForeignKey(User, on_delete=models.CASCADE, related_name= 'comment' )
위의 예에서 user와 comment의 관계에서 comment가 외래키를 가지고 user에 접근하는 것이기 때문에(정참조), 외래키의 이름을 comment라고 해두면 comment= user.comment.all() 이런식으로 접근이 된다.
class Rating(models.Model):
name = models.CharField(max_length=45)
rating = models.IntegerField()
def __str__(self):
return self.name
class Meta:
db_table = 'rating_conversions'
+----+--------+--------+
| id | name | rating |
+----+--------+--------+
| 1 | 아주 | 5 |
| 2 | 보통 | 3 |
| 3 | 별로 | 1 |
+----+--------+--------+
class ItemReview(models.Model):
user = models.ForeignKey('user.User', on_delete=models.CASCADE)
item = models.ForeignKey('item.Item', on_delete=models.CASCADE)
packaging_rating = models.ForeignKey('Rating', on_delete=models.SET_NULL, null=True, related_name='packaging')
fragrance_rating = models.ForeignKey('Rating', on_delete=models.SET_NULL, null=True, related_name='fragrance')
taste_rating = models.ForeignKey('Rating', on_delete=models.SET_NULL, null=True, related_name='taste')
grade3 = Rating.objects.get(id=3)
grade3.fragrance.all()
from review.models import *
In [6]: grade3 = Rating.objects.get(id=3)
In [7]: grade3
Out[7]: <Rating: 별로>
In [8]: grade3.fragrance.all()
Out[8]: <QuerySet []>
class BaseModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
view에서 처럼 모델에서도 코드의 재사용을 막고 효율을 높히기 위해 baseview를 만들어 준다.
class Meta:
abstract = True
이 클래스 자체가 추상화클래스가 되어 클래스의 클래스라고 생각하자.
메타 옵션에서 abstract = True 를 설정하면 엄마 모델은 실제로 또는 물리적으로 존재하지 않는 가상의 클래스가 된다. 그리고 새끼 모델들은 부모의 필드와 속성, 함수들을 다 물려받아 실체가 있는 DB 테이블이 된다.
그니까 상속관계 없이 자식이 독립적이게 된다는것이다.
# ❯ python manage.py makemigrations
# Migrations for 'contents':
# contents/migrations/0001_initial.py
# - Create model Content
# - Create model Image
# 보셈 베이스모델은 언급되지않음
def image_upload_to(instance, filename):
ext = filename.split('.')[-1]
return os.path.join(instance.UPLOAD_PATH, "%s.%s" % (uuid.uuid4(), ext))
# 16자리 고유한 아이디 생성
class Image(BaseModel):
UPLOAD_PATH = 'user-upload'
content = models.ForeignKey(Content, on_delete=models.CASCADE)
image = models.ImageField(upload_to=image_upload_to)
order = models.SmallIntegerField() # image numbering
class Meta:
unique_together = ['content', 'order']
ordering = ['order']
verbose_name_plural = "이미지"
새로 배운 것이다.
이미지업로드함수는 이미지를 업로드를 하는데 경로와 중요한 부분이 uuid.uuid4()를 가지고 임의의 16자리로 해서 그대로 올리기 그러니까 변경해서 올리는것이다.