-
django.6 가상환경 내에서 data 집어넣기Django 2020. 11. 28. 00:16728x90
1. 가상환경 생성
(westarbucks)
conda create -n westarbucks python=3.8
2. 가상환경 진입
진입후 가상환경내의 django, mysql, mysqlclient(mysql 설치시 자동설치) 설치
conda activate westarbucks
3. 프로젝트 생성
django-admin startproject westarbucks
4. App 생성
python3 manage.py startapp products
5. MySQL 실행 및 "나의 데이터베이스명"을 이용한 데이타베이스 생성
mysql -u root -p mysql> create database we_databse character set uft8mb4 collate uft8mb4_general_ci;
6. App의 models.py 에서 파이썬 코드를 이용한 테이블을 생성
(AqueryTools를 이용한 모범 모델링답안을 기준으로 함)
from django.db import models class Menu(models.Model): name = models.CharField(max_length=45) class Meta: db_table = 'menus' class Category(models.Model): menu = models.ForeignKey('Menu', on_delete=models.CASCADE) name = models.CharField(max_length=45) class Meta: db_table = 'categories' class Drink (models.Model): korean_name = models.CharField(max_length=45) english_name = models.CharField(max_length=45) description = models.TextField(max_length=300) category = models.ForeignKey('Category', on_delete=models.CASCADE) class Meta: db_table = 'drinks' class Image (models.Model): image_url = models.CharField(max_length=2000) drink = models.ForeignKey('Drink', on_delete=models.CASCADE) class Meta: db_table = 'images' class Allergy(models.Model): allergy_name = models.CharField(max_length=45) name = models.ManyToManyField('Drink', through="Allergy_drink") class Meta: db_table = 'allergys' class Allergy_drink(models.Model): allergy = models.ForeignKey('Allergy', on_delete=models.CASCADE) drink = models.ForeignKey('Drink', on_delete=models.CASCADE) class Meta: db_table = 'allergy_drinks' class Nutrition(models.Model): kcal = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) sodium = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) fat = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) sugar = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) protein = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) caffeine = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) dirnk_nu = models.ForeignKey('Drink', on_delete=models.CASCADE) class Meta: db_table = 'nutritions' class Size(models.Model): size_name = models.CharField(max_length=45) size_ml = models.CharField(max_length=45) size_ounce = models.CharField(max_length=45) nutrition = models.ForeignKey('Nutrition', on_delete=models.CASCADE) class Meta: db_table = 'sizes' # Create your models here.
7. makemigration -> migrate
활성화 하기 전 해야하는 것 makemigrations 라는 명령어로 내가 모델을 변경시킨 사실 (또는 생성했다는 사실)과 이 변경사항을 migration으로 저장시키고 싶다는 것을 Django에게 알려줘야한다.
python3 manage.py makemigrations westarbucks
그 다음은 migrate 명령어로 데이터베이스에 모델과 관련된 테이블을 생성하는 것이다.
python3 manage.py migrate
8. database 확인하기
show databases; use we_database; show tables;
9. database에 데이터 집어 넣기
django shell에 진입후 데이터 집어넣기 시작
python3 manage.py shell
이전 models.py에 작성한 클래스들을 모두 이용하기 위해
>>> from products.models import * # (app).models , *(models.py의 모든 변수,함수,클래스 사용하겠다)
9.1 step.1
Menu table - Create
Create method 인 create() 와 save() 를 사용
>>> Menu.objects.create(name="음료") >>> Menu.objects.create(name="음료") >>> a3 = Menu(name="상품") >>> a3.save() >>> a4 = Menu(name="카드") >>> a4.save()
bulk_create() method라는것도 있다.
>>> a1 = Menu(name="음료") >>> a2 = Menu(name="푸드") >>> Menu.objects.bulk_create([a1, a2])
MySQL 데이타베이스에서 Menu table 확인하기
>>> select * from menus; # Menu 클래스의 테이블의 명을 class Meta: 를 이용해 'menus'로 지정해줬기 때문
9.2 step.2
Menu table - Read
결과가 같다 즉, 음료의 id 값은 1이다
여기서 id란 menus 테이블의 Primary Key (고유키)를 뜻함
즉, get() method를 이용해 "음료"의 PK를 Read할 수 있다.Menu.objects.get(name="음료") Menu.objects.get(id=1)
각 메서드를 현 단계에서 사용해보았다
테이블에 데이터를 모두 넣었을때의 결과와 비교해보도록 하자all(), filter(), exclude(), values(), values_list()
9.3 step.3
Category table _ Create
이번 테이블에 데이터를 넣을때는 해당 테이블은 Menu 테이블의 id를 FK로 참조하고 있는 사실을 인지하고
데이터를 집어 넣도록 하자
먼저 a1 이라는 임의의 변수에 해당하는 Menu를 Read 한 뒤, 이를 Category 생성시 menu에 저장해주면
Menu의 PK를 찾아서 Read 한뒤 -> Category 테이블의 FK로 데이터를 넣을 수 있게 된다.
>>> a1 = Menu.objects.get(name="음료") >>> Category.objects.create(name="콜드 브루 커피", menu=a1) >>> Category.objects.create(name="블렌디드", menu=a1) # models.py에 Category 클래스를 정의할때 menu라는 Menu의 FK를 사용하는 변수를 사용함
>>> a2 = Menu.objects.get(name="푸드") >>> Category.objects.bulk_create([Category(name="브레드", menu=a2), Category(name="케이크", menu=a2)])
이제 Category 테이블을 확인해보자
MySQL >>> select * from categories;
9.4 step.4
Category table - Read
현재 해당 테이블은 Many To mon 관계에 있어 이전 Menu 테이블과는 달리 Read하기 조금 까다롭다
아래 장고 공식문서를 사용하며 여러번 사용해봐야 익숙해 질 수 있다.
docs.djangoproject.com/en/3.1/topics/db/examples/many_to_one/
Category table
all(), filter() 메서드 사용
>>> Category.objects.all() >>> Category.objects.filter(menu_id=1) OR Category.objects.filter(menu__name="음료") # (_) 갯수 주의 >>> Category.objects.filter(menu_id=2) OR Category.objects.filter(menu__name="푸드")
all()
filter()
Category 테이터 중 음료 Menu를 참조하고 있는 데이터만 출력
Category 테이터 중 푸드 Menu를 참조하고 있는 데이터만 출력
푸드 Menu를 참조하고 있는 Category의 모든 데이터들의 이름을 출력
(아래와 같이 반복문으로도 출력이가능)
for category in Category.objects.filter(menu__name="푸드"): print(category.name)
음료 Menu를 참조하고 있는 모든 Category 출력 (Queryset 형태)
>>> a1 = Menu.objects.get(name="음료") >>> a1.category_set.all()
음료 Menu를 참조하고 있는 Category 데이터의 갯수 출력
>>> a1 = Menu.objects.get(name="음료") >>> a1.category_set.count()
블렌디드 Category가 참조하고 있는 메뉴의 name 출력
>>> c2 = Category.objects.get(name="블렌디드") >>> c2.menu.name
9.5 step.5
모든 테이블의 데이터 집어 넣기
drink table - create
FK로 사용하는 Category id 별로 b1, b2에 저장하여 사용하자
(Drink 테이블은 Category 테이블을 참조하기 때문에 create시 read한 내용을 변수로 넣어 사용하기 위함)
하나하나 전부 타이핑으로 기입..
(크롤링 배우기 전 상태이므로, 크롤링에 대한 소중함을 배울수 있었다)
이제 english_name과 desc을 채워보자.
위와 동일한 방법으로 사용하였더니 아래와 같이 확인되었다.
objects가 15 일리가 없을텐데 말이다.
이전에 있던 Row에서 데이터를 생성하는게 아니라 새로운 Row를 생성해 데이터를 생성함을 확인 할 수 있었다.
filter() method를 이용해 e_name="NVC" 인 (삭제하고 싶은 데이터)를 선택하고 delete()로 지울 수 있다.
Drink.objects.filter(english_name="Nitro Vanilla Cream").delete()
현재 Drink id =1 번 Row에 e_name과 desc을 추가하려고 한다.
해당 Id 에 맞는 Row에 접근하고
각 column 별로 내용을 추가한 후 save()를 이용하여 값을 수정할 수 있었다.
>>> a1 = Drink.objects.get(id=1) >>> a1.english_name = "Nitro Vanilla Cream" >>> a1.description = "부드러운 목넘김의 나이트로 커피와 바닐라 크림의 매력을 한번에 느껴보세요!" >>> a1.save()
위와 같은 방법으로 하나 하나 정성스럽게 넣어주자.
(이럴거면 당연히 개발자는 필요없겠다)
Image table
Allergy table
아래와 같이 Allergy 테이블은 Drink 테이블과 many to many 관계로
name 이라는 manytomanyField를 인스턴스로 가지고 있다.
class Allergy(models.Model): allergy_name = models.CharField(max_length=45) name = models.ManyToManyField('Drink', through="Allergy_drink")
하지만 이전 FK를 가지고 있는 테이블과 달리
ManyToMany 를 가지고 있음에도 마치 가지고 있지 않는 것처럼
1차원(?)적으로 테이블에 데이터를 넣어 줄 수 있었다.
Django 에서는 ManyToMany 관계를 관리하는 테이블을 자동으로 생성한다고 한다.
그럼 Allergy 테이블을 만듬으로써 Allergy_drinks 라는 중간 테이블이 필요한 테이블이
모두 채워졌는다
그런데, 중간 테이블이 비워져있다. (해당 내용은 추후 ORM과 database 관계를 설명할때 한꺼번에 다뤄보자)
아래 models.py를 살펴보면
ManyToManyField를 사용 및 through 속성을 사용하였고
Allergy_drink 라는 중간테이블을 설정해주었다.
[ 인식하지는 못했지만 이처럼 중간 테이블을 설정해주는 것으르 생활화하자.
(이유: Django는 ManyToManyField를 사용하면 중간테이블을 자동으로 생성한다.) ]
class Allergy(models.Model): allergy_name = models.CharField(max_length=45) name = models.ManyToManyField('Drink', through="Allergy_drink") class Meta: db_table = 'allergys' class Allergy_drink(models.Model): allergy = models.ForeignKey('Allergy', on_delete=models.CASCADE) drink = models.ForeignKey('Drink', on_delete=models.CASCADE)
Allergy_drink - table (Many - To - Many 관계에서의 중간 테이블)
그럼 중간 테이블에는 값을 어떻게 넣을 수 있을까
고유의 인스턴스가 없으므로 해당 테이블의 컬럼은 N:N 관계에 있는 Drink 와 Allergy의 PK값으로만 이루어 진다.
따라서
1. Drink 테이블의 PK 값을 읽어 변수로 저장 (read)
2. Allergy 테이블의 PK값을 읽어 변수로 저장 (read)
3. 두 변수를 이용해 Allergy_drink 테이블의 column을 구성하도록 create 해주면 된다. (create)
Drink 테이블의 Korean_name이 "나이트로 바닐라 크림" 인 것의 Id 값을 읽자.
Allergy 테이블의 allergy_name이 "우유"인 것의 id값을 읽자.
Allergy_drink.objects.create(allergy_name=a1, drink=b1)
알레르기 유발 요인이 있는 음료만의 id를 읽고
어떤 알레르기가 있는지 알레르기만의 id를 읽고
위와 동일한 방식으로 데이터를 집어넣었다.(단순 반복)
models.py
from django.db import models class Menu(models.Model): name = models.CharField(max_length=45) class Meta: db_table = 'menus' class Category(models.Model): menu = models.ForeignKey('Menu', on_delete=models.CASCADE) name = models.CharField(max_length=45) class Meta: db_table = 'categories' class Drink (models.Model): korean_name = models.CharField(max_length=45) english_name = models.CharField(max_length=45) description = models.TextField(max_length=300) category = models.ForeignKey('Category', on_delete=models.CASCADE) class Meta: db_table = 'drinks' class Image (models.Model): image_url = models.CharField(max_length=2000) drink = models.ForeignKey('Drink', on_delete=models.CASCADE) class Meta: db_table = 'images' class Allergy(models.Model): allergy_name = models.CharField(max_length=45) name = models.ManyToManyField('Drink', through="Allergy_drink") class Meta: db_table = 'allergys' class Allergy_drink(models.Model): allergy = models.ForeignKey('Allergy', on_delete=models.CASCADE) drink = models.ForeignKey('Drink', on_delete=models.CASCADE) class Meta: db_table = 'allergy_drinks' class Nutrition(models.Model): kcal = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) sodium = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) fat = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) sugar = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) protein = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) caffeine = models.DecimalField(max_digits = 10, decimal_places = 2, null=True) dirnk_nu = models.ForeignKey('Drink', on_delete=models.CASCADE) class Meta: db_table = 'nutritions' class Size(models.Model): size_name = models.CharField(max_length=45) size_ml = models.CharField(max_length=45) size_ounce = models.CharField(max_length=45) nutrition = models.ForeignKey('Nutrition', on_delete=models.CASCADE) class Meta: db_table = 'sizes' # Create your models here.
Meun , Category Tables
Drink Table
Image Table
Allergy , Allergy_drink Tables
728x90'Django' 카테고리의 다른 글
django.8 Django Project 와 App 이해 (0) 2020.11.28 wecode_CRUD_1 과제 (0) 2020.11.28 django.4 스타벅스 모델링 과제_wecode (0) 2020.11.26 django.3 미니콘다 가상환경 설정 및 CRUD_1 (0) 2020.11.25 django.2 튜토리얼 (0) 2020.11.24