Django 101 : บทที่ 3 Model กับ Database และ migration
Django 101 : บทที่ 3 Model กับ Database และ migration
Django ใช้การเชื่อมต่อกับ Database แบบ (ORM) Object Relational Mapping (เราไม่จำเป็นต้องเขียนภาษา SQL เลย แต่เราจะเขียน ด้วย Python ผ่าน Class แทน (ความจริงมันเป็น Subclass ของ django.db.models.Model)
บทนี้ เราจะใช้ database เป็น mySQL
การติดตั้ง mySQL และการเชื่อมต่อ
ก่อนอื่น เราไปสร้าง Schema ใน mySQL (สมมติตั้งชื่อ mySQL ก็ได้) โดย Charactor set ให้เลือกเป็น UTF8 (รองรับภาษาไทย) กด apply 2 คร้ั้ง
กลับมาที่โปรเจค เราก็ต้อง install แพ็คเกจชื่อ mysql-connector-python ด้วยคำสั่งใน cml คือ pipenv install mysql-connector-python
แล้วเราก็เข้าไปแก้ไข setting.py เกี่ยวกับ database (ค่า default มันจะเป็น SQLite)
ก่อนอื่นเราต้องเพิ่ม
import mysql.connector.django
แก้ engine เป็น mysql.connector.django
แก้ NAME เป็น ชื่อ Schema ที่ตั้งไว้
เพิ่ม USER เป็น root
เพิ่ม PASSWORD เป็น password1234
เพิ่ม HOST เป็น 127.0.0.1
เพิ่ม PORT เป็น 3306
ถึงตรงนี้ เราจะใช้คำสั่ง python manage.py migrate
ถ้าขึ้น ok หมดแสดงว่า สำเร็จแล้ว
แต่ถ้าย้อนกลับไปดูที่ Database ตัว Django มันจะสร้าง table ให้เยอะแยะเลย(เพราะมันจะย้าย Admin ไปไว้ที่ mySQL ด้วยเลย)
Model and Migration
Code เริ่มต้นของ Model (เรียกว่า ทั้งสร้าง ทั้งเชื่อมต่อ เราจะเรียก Database จากไฟล์ Model.py นี้ได้เลย)from django.db import models
class all(models.Model): # คือมันสืบทอดมาจาก Class ชื่อ models.Model ของ Django นั่นเอง
title = models.CharField(max_length= 60)
price = models.IntegerField()
is_prem = models.BooleanField(Default = false)
promotion_end_at = models.DateTimeField(null=true)
description = models.TextField()
(โค๊ดด้านบนไม่ต่างกับ Create Table แต่ ID มันจะสร้างให้ Auto
แต่อย่าลืมย้อนกลับไปหน้า Setting ไปเพิ่ม App ด้วย และหากเราไม่ได้กำหนด Primary Key มันจะกำหนด ID เป็น Primary Key โดยอัตโนมัติ)
ทุกครั้งเมื่อมีการเปลี่ยนแปลง Model อย่าลืมใช้คำสั่ง run python manage.py makemigration ด้วย
หรือตัวอย่าง การสร้าง table สำหรับเก็บข้อมูล User
class user(models.Model)
Status = [
('unapprove' ,'Unapprove'),
('approved' , 'Approved' )
('banned', 'Banned')
]
name = models.CharField(max_length=60,primary_key = True)
email = models.CharField(max_length=60, unique= True)
status = models.CharField(max_length=15, choice= Status)
register_date= models.DateTimeField(auto_now_at= True)
makemigration
คือการ Sync Data กับ Project เมื่อมีการสร้าง Table/ หรือเปลี่ยนแปลง เราก็จำเป็นต้อง makemigration ด้วยคำสั่งดังนี้
python manage.py makemigrations ชื่อแอป
และเราจะเชื่อมข้อมูล ด้วยคำสั่ง migrate
python manage.py migration
การเรียกใช้ Database
ก่อนอื่นเราต้องลง bpythn เพื่อใช้ทดสอบ ด้วยคำสั่ง
1.install bpython --dev (สำหรับ development จะไม่อยู่ตอน employ ) ถ้าเราไม่ใช่ bpython เราต้องเข้า shell เพื่อทดสอบ
2. shell
ตอนนี้เริ่มต้นด้วยการเข้า shell ด้วยคำสั่ง python manage.py shell
เมื่อเข้า Mode Shell แล้ว เราก็สามารถพิมพ์คำสั่ง ใน Models ได้ นั่นเป็นเหตุผลว่า ทำไมเราควรใช้ bpython
โดยปกติ เราจะทำแค่ CRUD นี้
Create
Read
Update
Delete
คราวนี้เราจะมาลองกรอกข้อมูลด้วยคำสั่งพื้นฐาน
from app_food.model import foods
food1= foods()
food1.title= "xxx"
food1.price = 359
food1.save()
หรือกรอกแบบรวม
member = Member(firstname='Emil', lastname='Refsnes')
member.save()
กรณีต้องการ อัพเดท ก็แค่ save ทับใหม่แค่นั้น
Delete ก็แค่ใช้ food1.delete() แค่นั้น
สำหรับ การอ่าน Read Database
กรณีแรก อ่านทั้งหมด
from app_food.model import foods
all_food = foods.objects.all() # all = select * from table นั่นเอง
เวลาเรียกใช้งาน แค่ all_food จะเป็นข้อมูลแบบ List ที่มีกี่ Record ก็ว่าไป
กรณี ที่ 2 มีการกรองข้อมูล (Select Where)
premium_food = foods.objects.filter(premium=True)
กรณีที่ 3 เรียงจากข้อมูลทั้งหมด
all_food = foods.objects.all().order_by('is_premium') จากน้อยไปมาก
all_food = foods.objects.all().order_by('-is_premium') จากมากมาน้อย
กรณีที่ 4 การแบ่งหน้า (Pagination)
ต้องเข้าใจ การสไลด์ข้อมูล ใน Python จะได้ดังนี้
all_page_food = foods.objects.all()[0:1] # จะได้ข้อมูล 1 ตัวแรก
all_page_food = foods.objects.all()[0:2] # จะได้ข้อมูล 2 ตัวแรก
กรณีที่ 5 เรียกตัวเดียว
one_food = foods.objects.get(id=1)
กรณีที่ 6 ความสัมพันธ์ (จะมี 3 อย่างเท่านั้น คือ one-one one-many many-many เท่านั้น)
ถึงตรงนี้ต้องอธิบายเกี่ยวกับ foreign Key มันคือ คอลัมม์ลูกที่ถูกใช้เชื่อมต่อ กับคอลัมม์ของ table อื่นที่ส่วนใหญ่จะเป็น Primary Key (= ยูนิกและห้ามเป็น Null)
กรณีที่ 6.1 One-One
ก่อนอื่นต้องสร้าง Model (ที่ App หลัก) ยกตัวอย่างเช่น หากเชื่อมกับ user คนแรกเลือกแล้ว คนหลังจะเลือกไม่ได้ (เพราะ One-One)
โดยเราจะไปเขียนไว้ที่ Model ดังนี้
Food.models.OneToOneField('app_food.food' , on_delete=models.SET_NULL , null=True)
OneToOneField = เป็นการสร้างฝั่งใดฝั่งหนึ่ง ของแอป โดยมันต้องระบุชื่อ App.Model ของที่ต้องใช้
on_delete คือถ้า Table แม่ ถูกลบ จะให้เป็น Primary ของตารางแม่ เป็นค่าว่าง
ทำเสร็จเราต้อง makemigration และ migrate อีกที ถึงได้
เมื่อทำเสร็จ Model แรกที่อ้างอิง database จะมี Column เพิ่มขึ้นมา เพื่อเชื่อมไป Database ที่เชื่อม
กรณีที่ 6.2 Many-One
คราวนี้ต้องมี Foreign Key แล้ว (กรณีนี้จะเป็นจริงมากกว่า คือ ลูกค้าคนเดียว สามารถสั่งสินค้า ได้ซ้ำกัน)
เราต้องใส่ Foreign Key ไว้ที่ ฝั่งของ Many
บรรทัดข้างต้นจะกลายเป็น
Food.models.ForeignKey('app_food.food' , on_delete=models.SET_NULL , null=True)
เช่นเดิม อย่าลืม Makemigration และ migration ด้วย
เช่นเดิม Database จะเปลี่ยนไป โดยมี คอลัมม์ สำหรับเชื่อมต่อ แต่มันจะไม่ใช่ Unique แล้ว
กรณีที่ 6.3 Many-Many
อันนี้คือ การสร้างความสัมพันธ์ ของแอปส่วนใหญ่ เราต้องสร้าง Table พิเศษ เพื่อเพิ่มความสัมพันธ์ แต่ต้องเลือกแค่ฝั่งเดียว
ยกตัวอย่างเช่น User คนเดียว สามารถเลือกสินค้าได้หลายอย่าง (แต่ความจริงแล้ว สินค้าก็เลือก user ได้หลายคนเช่นกัน)
คำสั่งจะเขียนฝั่ง user จะได้ประมาณนี้
food_set = models.ManyToManyField(('app_food.food')
หลังจาก migration เรียบร้อย Database มันจะไม่มี Field เพิ่มแต่อย่างใด แต่มันจะมี Table พิเศษ เพิ่มขึ้นมา
ถึงตรงนี้ เราจะพูดถึง แต่ Many-Many แล้ว
เราจะเพิ่มข้อมูลใน Many-Many อย่างไร
ก่อนอื่นเราต้อง Import ทั้ง 2 Model เข้ามาก่อน
สิ่งแรกที่ต้องทำคือ Selected_food เลือกเฉพาะ ID ที่เขาเลือก มา
new_sub.food_set.set(Selected_food)
ความคิดเห็น
แสดงความคิดเห็น