TIL - 0205

Migration

manage.py makemigrations 선택적

  • 누군가가 서드파티에 만들어놓은 테이블이 있을 경우엔, 이미 만들어 놓았기 때문에 그땐, ` migrate`만 실행
  • 그러나 처음부터 만들땐, 둘 다 실행

Field type

minimal vaildation

  • 글자 제한이 있을 경우, 제한 글자 수까지만 장고에서 보여줌

Field options

  • null 값이 없는 것 / 데이터베이스와 관련
  • blank 빈값 / 빈 문자열 / 유효성 검사와 관련 blank=True이면 빈칸 생성이 가능. 데이터베이스에 영향이 없음

  • Date 필드 오류 blank=True했는데, 에러남 데이터베이스에 null조건이 있다. - 500 서버에러 데이터베이스에서 null을 허락하지 않기 때문에 발생 Date 필드의 경우, null을 허락하지 않음. 즉 blank=Truenull=True 둘 다 설정 되어야 데이터베이스에 null을 허용 할 수 있다. 문자열 외에는 null을 허용하지 않는다. (이 부분 찾아보기)

choices

YEAR_IN_SCHOOL_CHOICES = (
  ('FR','Freshman'),
  ('SO','Sophomore'),
)

데이터베이스에 저장 할때 좀더 간결하게 저장하여, 메모리 효율성을 높일 수 있음 그리고 사용자가 볼 때는 풀네임을 볼 수 있음

p.get_year_in_school_dispaly()
 # .get_FIELD(소문자)_dispaly()
 #  장고로직에 의해, 풀네임을 가져 올 수 있음

primary key

  • 따로 지정을 해주면 장고에서 자동으로 설정해놓은 id가 해제됨
  • primary key 를 변경하면, 데이터베이스에서 변경된 값으로 복사를 함.

Verbose Field names

# 첫번째 선택 인자에, 선택적 인자로 지정하면
# admin 페이지에서도 설정된 이름으로 출력
name = modles.CharField('이름',max_length=40)

# ForeignKey 경우
# verbose_name 으로 따로 지정
poll = models.Foreign Key(
  Poll,
  on_delete=models.CASCADE,
  verbose_name = "the related poll"
)

관계형데이터베이스

Django 다대일, 다대다 , 일대일 관계

A many-to-one relationship

ex) 선생님과 학생 관계 Teacher : Students = 1 : N

class Person(models.Model):
  name = models.CharField(max_length=100)
  Teacher = models.ForeignKey(
  'self',
  on_delete = models.SET_NULL,
  null = True,
  blank = True,
  )

ForeignKey 규칙

  • 외래키를 가지는 경우, 변수명을 참조 클래스 이름을 소문자로 표시

Many-to-Many relationship

  • 두개의 테이블에서만 정의가 가능하다
  • 선택을 하는 쪽에 ManyToManyField 을 설정
  • ex) 피자와 토핑
    ex) 자기자신의 모델을 여러개 가지는 경우는? 페이스북,트위터 친구관계
class Topping(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        verbose_name_plural = 'Basic - Topping'

    def __str__(self):
        return self.name


class Pizza(models.Model):
    name = models.CharField(max_length=50)
    toppings = models.ManyToManyField(Topping)

    class Meta:
        verbose_name_plural = 'Basic - Pizzas'

    def __str__(self):
        return self.name

이 경우, topping,pizza,pizza_toppings테이블 3개가 생성된다. pizza_toppingsManyToManyField로 지정하면서 자동으로 생성된 테이블

master_pizza.toppings.add(cheese,pepperoni,shrimp)

add()로 하면 바로 pizza_toppings테이블에 입력이 되기 때문에, save()를 하지 않아도 된다.

참고사이트

Extra fields on many-to-many relationship

  • 두개의 테이블에 대해 관련된 데이터를 다루고 싶을 때 이 테이블을 생성
  • 기본적인 ManyToMany관계 와 달리, 자동으로 중간 테이블이 생성되지 않는다.
  • through 로 중간 테이블을 지정한다.
  • 중간 모델은 두 테이블의 정보를 가지고 있어야 한다.
  • ex) PostLike 테이블이 PostUser 의 외래키를 가지고 있음
class Post(models.Model):
    title = models.CharField(max_length=50)
    like_users = models.ManyToManyField(
        'User',
        through='PostLike',
        # MTM으로 연결된 반대편에서
        # (지금의 경우 특정 User가 좋아요 누른
        #   Post목록을 가져오고 싶은 경우)
        # 자동 생성되는 역방향 매니저 이름인 post_set대신
        #   like_posts라는 이름을 사용하도록 한다
        # ex) user2.like_posts.all()
        related_name='like_posts',
    )

    def __str__(self):
        return self.title


class User(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class PostLike(models.Model):
    post = models.ForeignKey(
        Post,
        on_delete=models.CASCADE,
    )
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
    )
    created_date = models.DateTimeField(
        auto_now_add=True
    )


# 중계 데이터가 있는 경우, 중계테이블에서 ORM을 이용하여
# 데이터를 생성해야 한다.
# 왜냐하면 외래키로 받은 데이터 외에 다른 데이터는 어떤 형식으로 넣어줘야할지 모르기 때문에
PostLike.objects.create(post=p1,user=u1)

timezone

def __str__(self):

        return '"{title}"글의 좋아요({name}, {date})'.format(
        title=self.post.title,
        name=self.user.name,
        date=datetime.strftime(
            #   timezone.make_naive(self.created_date),
            timezone.localtime(self.created_date),
            '%Y.%m.%d'),

strftime : 현재 날짜와 시간을 문자열로 출력
참고자료

make_naive : time_zone으로 설정해놓은 나라 시간으로 출력 (UTC기준에서 서울 시간으로 변경)

make_aware : time_zone이 없는 경우, time_zone이 있는 경우로 바꿔주는 것 (바꿔주고 싶은 time_zone을 설정)

datetime.now(): time_zone은 없고, 그냥 현재 내 컴퓨터 시간을 출력함

timezone.now(): time_zone을 가지고 있고, UTC 기준으로 시간을 출력


오류

migrate가 안되요!
config/settings.py에 app으로 추가했는지 확 인 할것