มือใหม่ Django part 3: Admin page

Phai Panda
4 min readFeb 12, 2021

--

มือใหม่และผมได้เรียนรู้ร่วมกันแล้วว่า Django จะให้เรานิยามสิ่งที่ต้องการก่อน จากนั้นจึงค่อยสร้างและใช้งานในภายหลัง เราได้รู้จัก view และ model กันไปแล้ว หนนี้มาดูอีกว่า Django มีเครื่องมืออะไรเตรียมไว้ให้พวกเราได้ว้าวกันอีกไหม

ความเดิมจาก part ก่อนหน้า

เข้าประเด็นเลย งานปกติที่เรามักทำกันบ่อยครั้งกับข้อมูลในตารางของฐานข้อมูลคือ

  • เพิ่ม (create)
  • ดู (read)
  • ปรับปรุง (update)
  • ลบ (delete)

รวมแล้วเรียกว่า CRUD

ข้อสงสัยปนความเกียจคร้านมีอยู่ว่า ถ้าจะเขียนเว็บสักหลายหน้าเพื่อทำเรื่องเหล่านี้มันคงเสียเวลาน่าดู เนื่องจากข้อมูล (ขอเรียกว่า content หรือ data) ก็มีเยอะแยะไปหมด มือใหม่อาจบอกว่าไม่เห็นยากก็ไปใช้โปรแกรมจัดการฐานข้อมูลเลยสิ เขียน SQL เอาครับ แต่เปล่าเลย…ถ้าเราจะสร้างเว็บในการจัดการ content อย่าง CMS (ย่อมาจาก Content Management System) หรือเพื่ออำนวยความสะดวกแก่ผู้ใช้งานแบบจริงจัง พวกเขาไม่ต้องการเครื่องมือหลายตัวเพื่อทำงานชิ้นเดียวให้สำเร็จ ตรงกันข้ามพวกเขาจะถามหาสิทธิ์ในการเข้าไปแก้ไข content ที่ต้องการอย่างมีระบบ ง่ายดายและรู้สึกปลอดภัยมากกว่า ดังนั้นโยนโปรแกรมพวก command-line client หรือโปรแกรมอย่าง DB Browser for SQLite ออกจากหัวไปก่อน

กลับมาที่ข้อสงสัยปนความเกียจคร้าน Django จึงเสนอหนทางดูแลส่วนนี้โดยมันจะสร้างหน้าเว็บฝั่งผู้ดูแลระบบที่เรียกว่า content publishers ให้ เมื่อผู้ใช้งานที่เรียกว่า admin หรือ manager เข้าสู่ระบบแล้วก็จะสามารถ CRUD กับ content ที่ต้องการนั้นได้ทันที — จบปิ้ง

มาถึงตรงนี้ผมขอสรุปให้เห็นภาพง่ายๆดังนี้

  • Django จะแยกผู้ใช้งานออกเป็น 2 กลุ่ม คือ visitors กับ managers
  • visitors คือกลุ่มลูกค้าที่จะเห็น public site
  • managers คือกลุ่มผู้ดูแลที่จะเห็น content publishers
  • content ที่ปรากฏ ณ ​public site จะถูกเพิ่ม แก้ไขและลบโดยกลุ่ม managers

จาก part ที่ผ่านมาลองกลับไปรัน python3 manage.py runserver สืบเนื่องจากเราได้ migrate apps เป็นที่เรียบร้อย ผลคือ http://localhost:8000/polls/ ยังใช้ได้ปกติ

http://localhost:8000/polls is work!

Python shell

เป็น command-line interface ที่ใช้ interactive กับ Django APIs มาลองกันครับ

python3 manage.py shell

ผลลัพธ์

ลอง import คลาส Question และ Choice มาใช้งาน

from polls.models import Question, Choice

จากนั้นขอดู Question ทั้งหมด

Question.objects.all()

หรือขอดู Choice ทั้งหมด

Choice.objects.all()

ผลคือ <QuerySet []> แปลว่าว่างเปล่า ไม่มีของ

สร้าง Question

Question มี date time ฉะนั้นเพิ่ม import timezone ด้วย

from django.utils import timezone

แล้วพิมพ์คำถามเหมือนใน Python คือประกาศตัวแปรแล้วให้ค่า

q = Question(question_text="President of Thailand?", pub_date=timezone.now())

จากนั้นบันทึกลงฐานข้อมูล

q.save()

อยากเห็น id ที่ฐานข้อมูลสร้างให้ หรืออยากเห็น question_text หรืออยากเห็น pub_date ใช้เครื่องหมาย . ต่อท้ายตัวแปรที่สร้างได้เลย เช่น q.id , q.question_text , q.pub_date

ขอแก้ไข question_text หน่อย

q.question_text="เลือกใครเป็นนายก?"

บันทึก

q.save()

จากนั้นขอดู Question ทั้งหมดอีกครา Question.objects.all() ผลคือ

<QuerySet [<Question: Question object (1)>]>

อ่านไม่ออก 555+ เพื่อแก้ไขเรื่องนี้จะต้องทำ to string ให้กับคลาส Question

To String

ทำก็ต่อเมื่อต้องการอ่านผลลัพธ์จากออบเจกต์ของคลาสใน command-line

เปิดไฟล์ polls/models.py

เพิ่มฟังก์ชัน __str__ แล้วโยนตัวมันเองเป็น argument แรก

from django.db import modelsclass Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text

ขอทำ Choice ด้วยเลย

class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text

ทดสอบด้วยการออกจาก shell แล้วกลับเข้าไปใหม่

import Question แล้วเรียก Question.objects.all() ผลลัพธ์

สร้าง Choice

เราสามารถสร้าง Choice ที่มีความสัมพันธ์หนึ่งต่อหลายกับ Question ได้ด้วยคำสั่ง _set ตัวอย่างต่อไปนี้ หนึ่ง Question มีสาม Choices

from polls.models import Choice, Questionq = Question.objects.get(id=1)q.choice_set.create(choice_text="ลุงตู่", votes=0)q.choice_set.create(choice_text="พี่ธร", votes=0)q.choice_set.create(choice_text="พี่เต้", votes=0)

หากว่าต้องการดู Choices ทั้งหมดซึ่งได้ผลลัพธ์ไม่ต่างจาก Choice.objects.all() ก็ว่า

q.choice_set.all()

หรือนับจำนวนก็ว่า

q.choice_set.count()

ยังมีอีกหลายคำสั่งที่เกี่ยวข้องกับความสัมพันธ์ของ model หรือตารางในฐานข้อมูล สามารถอ่านเพิ่มเติม ที่นี่

Admin Page

เพื่อจะได้ชมว่า Django ได้สร้างหน้าเว็บฝั่งผู้ดูแลระบบที่เรียกว่า content publishers ให้อย่างไร สิ่งแรกที่เราต้องมีคือ admin user สร้างโดยคำสั่งนี้ครับ

python3 manage.py createsuperuser

Django จะให้กรอก username, email และ password

ผมได้เพิ่ม

  • username: admin
  • email: admin@mail.com
  • password: 1234

password ที่เดาได้ง่ายนั้นไม่ปลอดภัย Django จึงเตือนในเรื่องนี้ ทว่าสุดท้ายก็แล้วแต่ความต้องการของเรา

เรียกไปที่ http://localhost:8000/admin/ ผลลัพธ์

admin login page

กรอก username และ password ตามระเบียบจ้า

logged in admin page

ว้าว! ผมจำได้ว่าเพื่อนผมร้องว้าวออกมาเมื่อเห็นหน้านี้ครั้งแรก ราวกับว่าเขาอยู่ในอาณาจักรของ backend มาชั่วชีวิตเพิ่งได้เห็นว่าภาษา Python สามารถสร้าง frontend ได้ด้วย แลมันงดงามเหลือเหลือคณานับ ตาสว่าง!

แต่สามวินาทีหลังจากนั้นความฝันพลันมลายด้วยความสงสัยพร้อมกับคำถามที่ฟังแล้วขบขัน “ไหนล่ะพี่ธร?”

อันที่จริงมันต้องถามว่า Question และ Choice อยู่ที่ไหน?

Make the Polls app modifiable in the admin

เราจำต้องลงทะเบียนให้ admin page ทราบก่อนว่าจะเอา models ใดมาโชว์บ้าง

เปิดไฟล์ polls/admin.py แล้วเพิ่ม Question กับ Choice

from django.contrib import admin
from .models import Question, Choice
admin.site.register(Question)
admin.site.register(Choice)

ไม่จำเป็นต้อง restart server ใหม่ แค่ reload page เท่านั้น

ผลลัพธ์

กดเข้าไปชม Question

เลือกคำถามแรก กดเข้าไปเพื่อแก้ไขและบันทึกได้

หรือกดเข้าไปชม Choice จะเพิ่ม แก้ไข ลบ ตามใจปรารถนา

ทบทวน สิ่งนี้จึงเรียกว่า CRUD อันหมายถึง create, read, update และ delete ซึ่งมักทำบ่อยๆกับข้อมูลในตารางฐานข้อมูลอยู่แล้ว แน่นอนว่า Django รู้จึงจัดการให้เสร็จสรรพ

โอกาสถัดไปเราจะมาต่อกันที่ view ของ Polls app เพื่อเอาโหวตมาแสดงผล สวัสดีจ้า

--

--

No responses yet