Project : WASH Korea 모델링

GYUBIN ·2021년 11월 4일
1

위코드 1차 프로젝트


1. 데일리 미팅

미팅 내용

  • 제품 상세 페이지에 구매 수량을 정할 수 있는데 ERD Products엔 없는 이유가 무엇인지
    → Carts(장바구니)에 quantity 컬럼이 적용되어 있다
        실제로 마켓컬리 페이지에서 제품 페이지 - 장바구니간 이동해보며 확인해보니
        제품 페이지 내에서는 구매 수량에 대한 내용은 따로 없고 장바구니로 넘어갈 때 생기는 것을 확인할 수 있었다

  • 제품 리스트 페이지에서 정렬 기준 중 신제품순 정렬을 구현하려면 Products에 관련 내용 (ex. Is_new : True / False)이 있어야 하지 않는지
    → Products 와 Many to Many 관계로 연결된 Tags 에 NEW 라는 신제품을 알려줄 태그가 포함되어 있어서 해당 내용으로 구현할 수 있을 것 같다


2. 모델링

ERD 기반으로 users, products, carts, wishes 총 4개의 app의 models.py 작성

users/models.py

from django.db import models

class User(models.Model):
    user_id  = models.CharField(max_length=40)
    password   = models.CharField(max_length=200)
    name       = models.CharField(max_length=40)
    nickname   = models.CharField(max_length=40, null=True)
    email      = models.CharField(max_length=100, unique=True)
    contact    = models.CharField(max_length=15)
    address    = models.CharField(max_length=100, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        db_table = 'users'

users/models.py

from django.db import models

class Category(models.Model):
    name        = models.CharField(max_length=40)

    class Meta:
        db_table = 'categories'

class SubCategory(models.Model):
    name        = models.CharField(max_length=40)
    category    = models.ForeignKey('Category',on_delete=models.CASCADE)

    class Meta:
        db_table = 'sub_categories'

class Product(models.Model):
    name         = models.CharField(max_length=40)
    price        = models.DecimalField(max_digits=8, decimal_places=2)
    weight       = models.CharField(max_length=10)
    sub_name     = models.CharField(max_length=40)
    description  = models.TextField()
    sub_category = models.ForeignKey('SubCategory',on_delete=models.CASCADE)
    tag         = models.ManyToManyField('Tag', through='ProductTag')
    
    class Meta:
        db_table = 'products'

class Tag(models.Model):
    name = models.CharField(max_length=40)
    
    class Meta:
        db_table = 'tags'

class ProductTag(models.Model):
    product = models.ForeignKey('Product', on_delete=models.CASCADE)
    tag     = models.ForeignKey('Tag', on_delete=models.CASCADE)
   
    class Meta:
        db_table = 'products_tags'

class Image(models.Model):
    url     = models.CharField(max_length=2000)
    product = models.ForeignKey('Product', on_delete=models.CASCADE)

    class Meta:
        db_table = 'images'

carts/models.py

from django.db import models
 
class Cart (models.Model):
    user     = models.ForeignKey('users.User', on_delete=models.CASCADE)
    product  = models.ForeignKey('products.Product', on_delete=models.CASCADE)
    quantity = models.IntegerField(default=1)

    class Meta:
        db_table = 'carts'

wishes/models.py

from django.db import models
 
class Wish (models.Model):
    user    = models.ForeignKey('users.User', on_delete=models.CASCADE)
    product = models.ForeignKey('products.Product', on_delete=models.CASCADE)

    class Meta:
        db_table = 'wishes'

👏 에러 발생 👏

carts / wishes 에서 models.py를 처음 작성할 때 users 와 products 를 참조하기 때문에
from users.models import User , from products.models import Product 를 작성해주었다

그리고 나서 models.ForeignKey('User', on_delete=models.CASCADE)를 작성하고 마이그레이션을 하니 오류가 발생한다 그것도 아주 많이..

이유가 무엇인지 찾아보자 🤔

👉 Django 에서 다른 app의 모델을 참조하는 방법은 두 가지가 있다

  1. 클래스 자체를 전달하는 방법
    : from users.models import User
      models.ForeignKey(User, on_delete=models.CASCADE)
  2. 클래스 전달 없이 하는 방법
    : models.ForeignKey('users.User', on_delete=models.CASCADE)

이번에 확실히 알았으니 앞으로는 같은 이유로 에러는 보지 말자 .. 제발


3. 모델링 멘토 리뷰


1. 클래스 명 / 테이블 명 지정

class Image(models.Model):
    url         = models.CharField(max_length=200)
    product      = models.ForeignKey('Product', on_delete=models.CASCADE)
    class Meta:
        db_table = 'image'
-------------------------------------------------------------------------
class ProductImage(models.Model):
    url    = models.CharField(max_length=2000)
    product = models.ForeignKey('Product', on_delete=models.CASCADE)
    class Meta:
        db_table = 'product_images'

이미지의 경우 여러 종류의 이미지 테이블이 생길 수 있기에 어떤 이미지를 저장하는 테이블인지 나타내주는 것이 좋다
이미지의 url의 경우 크기가 가볍게 500이 넘는 것들도 많기에 크기를 넉넉하게 잡아주면 좋다

class User(models.Model):
    user_id	     = models.CharField(max_length=40)
-------------------------------------------------------------------
class User(models.Model):
    user_name = models.CharField(max_length=40, unique=True)

회원가입 할 때 사용하는 ID는 필드는 보통 user_name으로 사용한다
그리고 ID는 유일한 값이여야 하기 때문에 unique 속성을 걸어주면 좋다
user_name 이외에도 unique 속성을 필요한 곳이 있다고 생각되면 추가하자
모든 파일에서 각 블럭별 = 기준으로 정렬 잘 하자

User 클래스 중 unique 속성이 필요한 곳은 id 외에는 더 이상 없는 것 같아 더 이상 추가하진 않았다


2. foreignkey를 지정할 때 on_delete 속성으로 전부 CASCADE을 사용

CASCADE 이외의 어떤 속성이 있고, 각각 어떤 역할을 하는지 알아보세요

on_delete 속성에는 총 6가지가 있다

CASCADE, PROTECT, SET_NULL, SET_DEFAULT, SET(), DO_NOTHING

  1. CASCADE : 참조 값이 삭제되면 같이 삭제된다
    ex. 게시글이 삭제되면 댓글도 같이 삭제된다

  2. PROTECT : 참조 값이 삭제될 때 에러가 발생한다
    ex. 댓글이 있는 게시글은 삭제를 할 수 없다

  3. SET_NULL : 참조 값이 삭제되면 null 값으로 변경된다
    ex. 게시글이 삭제되면 댓글은 DB에 남는다

  4. SET_DEFAULT : 참조 값이 삭제되면 default 값으로 변경된다
    ex. 게시글이 삭제되면 댓글은 지정된 default 게시글로 자동 할당된다

  5. SET() : SET_DEFAULT와 유사한 개념 ( 작동이 SQL에서 되냐 Django에서 되냐..? 확실한 개념 정리x )

  6. DO_NOTHING : 참조 값이 삭제되도 아무 작업을 하지 않는다
    ex. 댓글은 존재하지 않는 게시글을 참조하고 있어서 참조무결성을 해칠 수 있다

카테고리 > 서브카테고리 > 프로덕트의 참조관계는 삭제가 되면 안된다고 생각해서 CASCADE 에서 PROTECT로 바꾸어 주었다

프로덕트와 태그, 유저와 위시리스트/카트의 경우에는 CASCADE 가 맞다고 생각되어 그대로 두었다

3. 추가

    contact    = models.CharField(max_length=15)
    address	   = models.CharField(max_length=100, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
-----------------------------------------------------------------
    contact    = models.CharField(max_length=15)
    address	 = models.CharField(max_length=100, null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

VSCode에서 간격에 맞게 수정해서 다시 PR을 했지만 깃허브에서 보이는 코드의 간격은 또 다르다..

VSCode에서는 맞게 보여도 실제로 올라온 코드는 수정이 안 되어 있을 수 있다고 한다

앞으로는 항상 push 후에는 코드가 잘 올라갔는지 확인해보자

vim에서 다시 확인하니 간격이 잘못된 것이 확인되어 다시 수정했다 !


4. 모델링 수정사항 발생


프론트 측과 미팅 중 카테고리 / 서브카테고리에서도 이미지와 텍스트가 필요한 것이 확인되었다

class Category(models.Model):
    name        = models.CharField(max_length=40)
    image       = models.CharField(max_length=2000)
    description = models.CharField(max_length=100)

    class Meta:
        db_table = 'categories'

class SubCategory(models.Model):
    name        = models.CharField(max_length=40)
    image       = models.CharField(max_length=2000)
    description = models.CharField(max_length=100)
    category    = models.ForeignKey('Category',on_delete=models.PROTECT)

    class Meta:
        db_table = 'sub_categories'

카테고리 / 서브카테고리에도 이미지, 디스크립션 컬럼을 추가해서 다시 migrate했다 !

0개의 댓글

관련 채용 정보