จุดเด่นของ Django: โมเดล ผู้ดูแลระบบ และการควบคุมฐานข้อมูลเชิงสัมพันธ์ (ตอนที่ 3)

เผยแพร่แล้ว: 2022-03-10
สรุปอย่างย่อ ↬ แผงผู้ดูแลระบบเป็นหนึ่งในคุณสมบัติที่ทรงพลังและยืดหยุ่นที่สุดที่เฟรมเวิร์กเว็บ Django มอบให้ ซึ่งรวมเอาฟังก์ชันการทำงานแบบทันทีทันใดเข้ากับการปรับแต่งที่ไม่จำกัด เราจะใช้แผงการดูแลระบบเพื่อเรียนรู้เกี่ยวกับการสร้างแบบจำลองและการโต้ตอบกับฐานข้อมูลเชิงสัมพันธ์ใน Django โดยใช้โครงการตัวอย่างตามระบบสินค้าคงคลังของห้องสมุด

ก่อนที่เราจะเริ่มต้น ฉันต้องการทราบว่าความสามารถในการดูแลระบบในตัวของ Django แม้จะปรับแต่งแล้ว ไม่ได้มีไว้สำหรับผู้ใช้ปลายทาง แผงผู้ดูแลระบบมีอยู่ในฐานะนักพัฒนา ผู้ปฏิบัติงาน และเครื่องมือผู้ดูแลระบบสำหรับการสร้างและบำรุงรักษาซอฟต์แวร์ ไม่ได้มีจุดประสงค์เพื่อใช้ให้ความสามารถในการกลั่นกรองผู้ใช้ปลายทาง หรือความสามารถอื่นๆ ของผู้ดูแลระบบบนแพลตฟอร์มที่คุณพัฒนา

บทความนี้มีพื้นฐานมาจากสมมติฐานในสองส่วน:

  1. แผงผู้ดูแลระบบ Django นั้นใช้งานง่ายมาก โดยพื้นฐานแล้วคุณรู้วิธีใช้งานอยู่แล้ว
  2. แผงผู้ดูแลระบบ Django มีประสิทธิภาพมากจนเราสามารถใช้เป็นเครื่องมือในการเรียนรู้เกี่ยวกับการแสดงข้อมูลในฐานข้อมูลเชิงสัมพันธ์โดยใช้โมเดล Django

ฉันเสนอแนวคิดเหล่านี้โดยมีข้อแม้ว่าเรายังต้องเขียนโค้ดการกำหนดค่าบางอย่างเพื่อเปิดใช้งานความสามารถที่มีประสิทธิภาพมากขึ้นของแผงผู้ดูแลระบบ และเรายังคงต้องใช้ ORM (การทำแผนที่เชิงวัตถุสัมพันธ์) ของ Django เพื่อระบุการแสดงข้อมูล ในระบบของเรา

การอ่านที่แนะนำ

“Django Highlights” เป็นชุดที่นำเสนอแนวคิดที่สำคัญของการพัฒนาเว็บใน Django คุณอาจต้องการอ่านเกี่ยวกับการจัดหาขั้นตอนการตรวจสอบสิทธิ์ผู้ใช้ที่ปลอดภัย และติดตามการสาธิตเกี่ยวกับการใช้เทมเพลต Django เพื่อเขียนหน้าที่ซับซ้อน

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

การตั้งค่า

เรากำลังจะดำเนินการกับโครงการตัวอย่างในบทความนี้ โครงการจำลองข้อมูลบางอย่างที่ห้องสมุดจะจัดเก็บเกี่ยวกับหนังสือและผู้อุปถัมภ์ ตัวอย่างควรใช้ได้กับระบบหลายประเภทที่จัดการผู้ใช้และ/หรือสินค้าคงคลัง ข้อมูลคร่าวๆ มีลักษณะดังนี้:

โมเดลข้อมูล (ตัวอย่างขนาดใหญ่)

โปรดทำตามขั้นตอนต่อไปนี้เพื่อให้โค้ดตัวอย่างทำงานบนเครื่องของคุณ

1. การติดตั้งแพ็คเกจ

เมื่อติดตั้ง Python 3.6 ขึ้นไป ให้สร้างไดเร็กทอรีและสภาพแวดล้อมเสมือน จากนั้น ติดตั้งแพ็คเกจต่อไปนี้:

 pip install django django-grappelli

Django เป็นเว็บเฟรมเวิร์กที่เรากำลังทำงานด้วยในบทความนี้ ( django-grappelli เป็นธีมแผงผู้ดูแลระบบที่เราจะกล่าวถึงสั้น ๆ )

2. รับโครงการ

เมื่อติดตั้งแพ็คเกจก่อนหน้าแล้ว ให้ดาวน์โหลดโค้ดตัวอย่างจาก GitHub วิ่ง:

 git clone https://github.com/philipkiely/library_records.git cd library_records/library

3. การสร้าง Superuser

ใช้คำสั่งต่อไปนี้ ตั้งค่าฐานข้อมูลของคุณและสร้าง superuser อินเทอร์เฟซบรรทัดคำสั่งจะแนะนำคุณตลอดขั้นตอนการสร้าง superuser บัญชีผู้ใช้ superuser ของคุณจะเป็นช่องทางให้คุณเข้าถึงแผงการดูแลระบบในทันที ดังนั้นอย่าลืมจำรหัสผ่านที่คุณตั้งไว้ ใช้:

 python manage.py migrate python manage.py createsuperuser

4. กำลังโหลดข้อมูล

สำหรับการสำรวจของเรา ฉันได้สร้างชุดข้อมูลที่เรียกว่าฟิกซ์เจอร์ ซึ่งคุณสามารถโหลดลงในฐานข้อมูลได้ (เพิ่มเติมเกี่ยวกับวิธีการสร้างฟิกซ์เจอร์ที่ส่วนท้ายของบทความ) ใช้โปรแกรมติดตั้งเพื่อเติมฐานข้อมูลของคุณก่อนที่จะสำรวจในแผงการดูแลระบบ วิ่ง:

 python manage.py loaddata ../fixture.json

5. การดำเนินโครงการตัวอย่าง

ในที่สุด คุณก็พร้อมที่จะรันโค้ดตัวอย่างแล้ว ในการรันเซิร์ฟเวอร์ ให้ใช้คำสั่งต่อไปนี้:

 python manage.py runserver

เปิดเบราว์เซอร์ของคุณไปที่ https://127.0.0.1:8000 เพื่อดูโครงการ โปรดทราบว่าคุณจะถูกนำไปยังแผงการดูแลระบบที่ /admin/ โดยอัตโนมัติ ฉันทำสำเร็จด้วยการกำหนดค่าต่อไปนี้ใน library/urls.py :

 from django.contrib import admin from django.urls import path from records import views urlpatterns = [ path('admin/', admin.site.urls), path('', views.index), ]

รวมกับการเปลี่ยนเส้นทางอย่างง่ายต่อไปนี้ใน records/views.py :

 from django.http import HttpResponseRedirect def index(request): return HttpResponseRedirect('/admin/')

การใช้แผงการดูแลระบบ

เราทำได้! เมื่อคุณโหลดหน้าของคุณ คุณควรเห็นสิ่งต่อไปนี้:

หน้าหลักของแผงการดูแลระบบ Django (ตัวอย่างขนาดใหญ่)

มุมมองนี้ทำได้โดยใช้รหัสสำเร็จรูปต่อไปนี้ใน records/admin.py :

 from django.contrib import admin from .models import Book, Patron, Copy admin.site.register(Book) admin.site.register(Copy) admin.site.register(Patron)

มุมมองนี้ควรให้ความเข้าใจเบื้องต้นเกี่ยวกับข้อมูลที่ระบบเก็บไว้แก่คุณ ฉันจะลบความลึกลับบางอย่างออก: Groups และ Users ถูกกำหนดโดย Django และจัดเก็บข้อมูลและการอนุญาตสำหรับบัญชีในระบบ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับรูปแบบ User ใช้ได้ในบทความก่อนหน้าในชุดนี้ Books Copys และ Patrons คือตารางในฐานข้อมูลที่เราสร้างขึ้นเมื่อเรียกใช้การย้ายข้อมูลและเติมโดยการโหลดโปรแกรมติดตั้ง โปรดทราบว่า Django สร้างพหูพจน์ชื่อรุ่นอย่างไร้เดียงสาด้วยการเติม “s” ต่อท้าย แม้ในกรณีเช่น “สำเนา” ซึ่งสะกดผิด

โมเดลข้อมูล (ตัวอย่างขนาดใหญ่)

ในโครงการของเรา Book คือบันทึกที่มีชื่อหนังสือ ผู้แต่ง วันที่ตีพิมพ์ และ ISBN (หมายเลขหนังสือมาตรฐานสากล) ห้องสมุดเก็บรักษา Copy ของหนังสือแต่ละ Book หรืออาจมีหลายเล่ม Copy แต่ละฉบับสามารถตรวจสอบได้โดย Patron หรือสามารถเช็คอินได้ในขณะนี้ Patron เป็นส่วนเสริมของ User ที่บันทึกที่อยู่และวันเกิดของพวกเขา

สร้าง อ่าน อัปเดต ทำลาย

ความสามารถมาตรฐานอย่างหนึ่งของแผงการดูแลระบบคือการเพิ่มอินสแตนซ์ของแต่ละรุ่น คลิกที่ "หนังสือ" เพื่อไปที่หน้าของโมเดล แล้วคลิกปุ่ม "เพิ่มหนังสือ" ที่มุมบนขวา การทำเช่นนั้นจะดึงแบบฟอร์มขึ้นมา ซึ่งคุณสามารถกรอกและบันทึกเพื่อสร้างหนังสือได้

สร้างหนังสือ (ตัวอย่างขนาดใหญ่)

การสร้าง Patron เผยให้เห็นความสามารถในตัวอื่นของแบบฟอร์มการสร้างของผู้ดูแลระบบ: คุณสามารถสร้างแบบจำลองที่เชื่อมต่อได้โดยตรงจากแบบฟอร์มเดียวกัน ภาพหน้าจอด้านล่างแสดงป๊อปอัปที่เรียกใช้โดยเครื่องหมายบวกสีเขียวทางด้านขวาของเมนูแบบเลื่อนลง User ดังนั้น คุณสามารถสร้างทั้งสองรุ่นได้ในหน้าผู้ดูแลระบบเดียวกัน

สร้างผู้อุปถัมภ์ (ตัวอย่างขนาดใหญ่)

คุณสามารถสร้าง COPY ได้โดยใช้กลไกเดียวกัน

สำหรับแต่ละระเบียน คุณสามารถคลิกแถวเพื่อแก้ไขโดยใช้แบบฟอร์มเดียวกัน คุณยังสามารถลบเรกคอร์ดได้โดยใช้การดำเนินการของผู้ดูแลระบบ

การดำเนินการของผู้ดูแลระบบ

แม้ว่าความสามารถในตัวของแผงการดูแลระบบจะมีประโยชน์อย่างกว้างขวาง แต่คุณสามารถสร้างเครื่องมือของคุณเองได้โดยใช้การดำเนินการของผู้ดูแลระบบ เราจะสร้างสองรายการ: ชุดแรกสำหรับสร้างสำเนาหนังสือและอีกชุดสำหรับเช็คอินหนังสือที่ส่งคืนในห้องสมุดแล้ว

หากต้องการสร้าง Copy Book ให้ไปที่ URL /admin/records/book/ และใช้เมนูแบบเลื่อนลง "การดำเนินการ" เพื่อเลือก "เพิ่มสำเนาของหนังสือ" จากนั้นใช้ช่องทำเครื่องหมายที่คอลัมน์ด้านซ้าย ของตารางเพื่อเลือกหนังสือหรือหนังสือที่จะเพิ่มสำเนาไปยังสินค้าคงคลัง

สร้างการดำเนินการคัดลอก (ตัวอย่างขนาดใหญ่)

การสร้างสิ่งนี้ขึ้นอยู่กับวิธีการของแบบจำลองที่เราจะกล่าวถึงในภายหลัง เราสามารถเรียกได้ว่าเป็นการดำเนินการของผู้ดูแลระบบโดยการสร้างคลาส ModelAdmin สำหรับโมเดล Profile ดังต่อไปนี้ใน records/admin.py :

 from django.contrib import admin from .models import Book, Patron, Copy class BookAdmin(admin.ModelAdmin): list_display = ("title", "author", "published") actions = ["make_copys"] def make_copys(self, request, queryset): for q in queryset: q.make_copy() self.message_user(request, "copy(s) created") make_copys.short_description = "Add a copy of book(s)" admin.site.register(Book, BookAdmin)

คุณสมบัติ list_display แสดงว่าฟิลด์ใดที่ใช้แทนโมเดลในหน้าภาพรวมของโมเดล คุณสมบัติ actions แสดงรายการการดำเนินการของผู้ดูแลระบบ การดำเนินการของผู้ดูแลระบบถูกกำหนดให้เป็นฟังก์ชันภายใน BookAdmin และรับอาร์กิวเมนต์สามอย่าง: ตัวอ็อบเจ็กต์ admin เอง คำขอ (คำขอ HTTP จริงที่ส่งโดยไคลเอ็นต์) และชุดการสืบค้น (รายการของอ็อบเจ็กต์ที่มีช่องทำเครื่องหมายไว้) เราดำเนินการแบบเดียวกันกับแต่ละรายการในชุดการสืบค้น จากนั้นแจ้งให้ผู้ใช้ทราบว่าการดำเนินการเสร็จสิ้นแล้ว การดำเนินการของผู้ดูแลระบบทุกครั้งต้องมีคำอธิบายสั้นๆ เพื่อให้สามารถระบุได้อย่างถูกต้องในเมนูแบบเลื่อนลง สุดท้ายนี้ เราได้เพิ่ม BookAdmin เมื่อลงทะเบียนโมเดล

การเขียนการดำเนินการของผู้ดูแลระบบสำหรับการตั้งค่าคุณสมบัติเป็นกลุ่มนั้นค่อนข้างซ้ำซาก นี่คือรหัสสำหรับตรวจสอบ Copy สังเกตว่ามันใกล้เคียงกับการกระทำก่อนหน้า

 from django.contrib import admin from .models import Book, Patron, Copy class CopyAdmin(admin.ModelAdmin): actions = ["check_in_copys"] def check_in_copys(self, request, queryset): for q in queryset: q.check_in() self.message_user(request, "copy(s) checked in") check_in_copys.short_description = "Check in copy(s)" admin.site.register(Copy, CopyAdmin)

ธีมผู้ดูแลระบบ

โดยค่าเริ่มต้น Django มีสไตล์ที่ค่อนข้างเรียบง่ายสำหรับแผงการดูแลระบบ คุณสามารถสร้างธีมของคุณเองหรือใช้ธีมของบุคคลที่สามเพื่อให้แผงการดูแลระบบมีรูปลักษณ์ใหม่ ธีมโอเพนซอร์ซยอดนิยมอย่างหนึ่งคือ grappelli ซึ่งเราติดตั้งไว้ก่อนหน้าในบทความ คุณสามารถดูเอกสารประกอบสำหรับความสามารถทั้งหมดได้

การติดตั้งธีมนั้นค่อนข้างตรงไปตรงมา เพียงสองบรรทัดเท่านั้น ขั้นแรก เพิ่ม grappelli ลงใน INSTALLED_APPS ดังนี้ใน library/settings.py :

 INSTALLED_APPS = [ 'grappelli', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'records', ]

จากนั้นปรับ library/urls.py :

 from django.contrib import admin from django.urls import path, include from records import views urlpatterns = [ path('grappelli/', include('grappelli.urls')), path('admin/', admin.site.urls), path('', views.index), ]

เมื่อมีการเปลี่ยนแปลงเหล่านั้น แผงผู้ดูแลระบบควรมีลักษณะดังนี้:

แผงผู้ดูแลระบบพร้อมธีม (ตัวอย่างขนาดใหญ่)

มีธีมอื่นๆ มากมาย และคุณสามารถพัฒนาธีมของคุณเองได้อีกครั้ง ฉันจะใช้รูปลักษณ์เริ่มต้นสำหรับส่วนที่เหลือของบทความนี้

ทำความเข้าใจโมเดล

ตอนนี้ คุณคุ้นเคยกับแผงการดูแลระบบและใช้งานเพื่อนำทางข้อมูลแล้ว มาดูโมเดลที่กำหนดโครงสร้างฐานข้อมูลของเรากัน แต่ละรุ่นแสดงหนึ่งตารางในฐานข้อมูลเชิงสัมพันธ์

ฐานข้อมูลเชิงสัมพันธ์จัดเก็บข้อมูลในตารางอย่างน้อยหนึ่งตาราง ตารางเหล่านี้แต่ละตารางมีโครงสร้างคอลัมน์ที่ระบุ รวมถึงคีย์หลัก (ตัวระบุที่ไม่ซ้ำกันสำหรับแต่ละองค์ประกอบ) และคอลัมน์ของค่าอย่างน้อยหนึ่งคอลัมน์ ซึ่งมีหลายประเภท เช่น สตริง จำนวนเต็ม และวันที่ แต่ละอ็อบเจ็กต์ที่จัดเก็บไว้ในฐานข้อมูลจะแสดงเป็นแถวเดียว ส่วน "เชิงสัมพันธ์" ของชื่อนั้นมาจากคุณลักษณะที่สำคัญที่สุดของเทคโนโลยีที่อาจเรียกได้ว่าเป็น นั่นคือ การสร้างความสัมพันธ์ระหว่างตาราง วัตถุ (แถว) สามารถมีหนึ่งต่อหนึ่ง หนึ่งต่อกลุ่ม (คีย์ต่างประเทศ) หรือการแมปแบบกลุ่มต่อกลุ่มกับแถวในตารางอื่น เราจะพูดถึงเรื่องนี้เพิ่มเติมในตัวอย่าง

โดยค่าเริ่มต้น Django ใช้ SQLite3 เพื่อการพัฒนา SQLite3 เป็นเครื่องมือฐานข้อมูลเชิงสัมพันธ์อย่างง่าย และฐานข้อมูลของคุณถูกสร้างขึ้นโดยอัตโนมัติเป็น db.sqlite3 ในครั้งแรกที่คุณเรียกใช้ python manage.py migrate เราจะดำเนินการต่อด้วย SQLite3 สำหรับบทความนี้ แต่ไม่เหมาะสำหรับการใช้งานจริง เนื่องจากโดยหลักแล้ว การเขียนทับสามารถเกิดขึ้นได้กับผู้ใช้ที่ทำงานพร้อมกัน ในการผลิตหรือเมื่อเขียนระบบที่คุณตั้งใจจะใช้งานในวันหนึ่ง ให้ใช้ PostgreSQL หรือ MySQL

Django ใช้โมเดลเพื่อเชื่อมต่อกับฐานข้อมูล การใช้ส่วนหนึ่งของ ORM ของ Django ไฟล์ records/models.py มีหลายโมเดล ซึ่งช่วยให้สามารถระบุฟิลด์ คุณสมบัติ และเมธอดสำหรับแต่ละอ็อบเจ็กต์ได้ เมื่อสร้างแบบจำลอง เรามุ่งมั่นเพื่อสถาปัตยกรรม "โมเดลอ้วน" ด้วยเหตุผล ซึ่งหมายความว่าควรจัดการการตรวจสอบความถูกต้องของข้อมูล การแยกวิเคราะห์ การประมวลผล ตรรกะทางธุรกิจ การจัดการข้อยกเว้น การแก้ไขขอบเคส และงานที่คล้ายกันให้มากที่สุดเท่าที่จะเป็นไปได้ในข้อมูลจำเพาะของตัวแบบ ภายใต้ประทุน โมเดล Django นั้นซับซ้อนมาก เป็นออบเจ็กต์ที่มีลักษณะเด่นพร้อมพฤติกรรมเริ่มต้นที่มีประโยชน์อย่างกว้างขวาง สิ่งนี้ทำให้สถาปัตยกรรม "Fat Model" ทำได้ง่ายโดยไม่ต้องเขียนโค้ดจำนวนมาก

มาดูโมเดลทั้งสามกันในแอปพลิเคชันตัวอย่างของเรา เราไม่สามารถครอบคลุมทุกอย่างได้ เนื่องจากนี่ควรจะเป็นบทความเบื้องต้น ไม่ใช่เอกสารฉบับสมบูรณ์ของเฟรมเวิร์ก Django แต่ฉันจะเน้นตัวเลือกที่สำคัญที่สุดที่ฉันทำในการสร้างโมเดลง่ายๆ เหล่านี้

คลาส Book เป็นโมเดลที่ตรงไปตรงมาที่สุด นี่คือจาก records/models.py :

 from django.db import models class Book(models.Model): title = models.CharField(max_length=300) author = models.CharField(max_length=150) published = models.DateField() isbn = models.IntegerField(unique=True) def __str__(self): return self.title + " by " + self.author def make_copy(self): Copy.objects.create(book=self)

ฟิลด์ CharField ทั้งหมดต้องมีแอตทริบิวต์ max_length ที่ระบุ ความยาวทั่วไปคือ 150 อักขระ ซึ่งฉันเพิ่มเป็นสองเท่าสำหรับ title ในกรณีที่ชื่อเรื่องยาวมาก แน่นอนว่ายังมีขีดจำกัดตามอำเภอใจซึ่งอาจเกินได้ สำหรับความยาวของข้อความที่ไม่ จำกัด ให้ใช้ TextField ฟิลด์ที่ published คือ DateField เวลาที่หนังสือถูกตีพิมพ์ไม่สำคัญ แต่ถ้าเป็นเช่นนั้นฉันจะใช้ DateTimeField สุดท้าย ISBN เป็นจำนวนเต็ม (ISBN คือ 10 หรือ 13 หลัก ดังนั้นทั้งหมดจึงพอดีในค่าสูงสุดของจำนวนเต็ม) และเราใช้ unique=True เนื่องจากไม่มีหนังสือสองเล่มใดที่มี ISBN เดียวกันได้ ซึ่งจากนั้นจะบังคับใช้ในระดับฐานข้อมูล

ออบเจ็กต์ทั้งหมดมีเมธอด __str__(self) ที่กำหนดการแสดงสตริง เราลบล้างการใช้งานเริ่มต้นโดยคลาส models.Model และแทนหนังสือเป็น "ชื่อโดยผู้แต่ง" ในทุกที่ที่โมเดลจะแสดงเป็นสตริง จำได้ว่าก่อนหน้านี้เราใช้ list_display ในวัตถุ admin ของ Book เพื่อกำหนดว่าฟิลด์ใดที่จะแสดงในรายการของแผงการดูแลระบบ หาก list_display รายการผู้ดูแลระบบแทนจะแสดงการแสดงสตริงของโมเดล เช่นเดียวกับที่จะแสดงสำหรับทั้ง Patron และ Copy

สุดท้าย เรามีวิธีการเกี่ยวกับ Book ที่เราเรียกในการดำเนินการของผู้ดูแลระบบที่เราเขียนไว้ก่อนหน้านี้ ฟังก์ชันนี้สร้าง Copy ที่เกี่ยวข้องกับอินสแตนซ์ของ Book ในฐานข้อมูล

ย้ายไปยัง Patron โมเดลนี้แนะนำแนวคิดของความสัมพันธ์แบบหนึ่งต่อหนึ่ง ในกรณีนี้ด้วยโมเดล User ในตัว ลองดูจาก records/models.py :

 from django.db import models from django.contrib.auth.models import User class Patron(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) address = models.CharField(max_length=150) dob = models.DateField() def __str__(self): return self.user.username

ฟิลด์ user ไม่ใช่ฟังก์ชัน bijective อย่างแน่นอน อาจมีอินสแตนซ์ของ User ที่ไม่มีอินสแตนซ์ของ Patron ที่เกี่ยวข้อง อย่างไรก็ตาม User ไม่สามารถเชื่อมโยงกับอินสแตนซ์ของ Patron ได้มากกว่าหนึ่งราย และ Patron ไม่สามารถ ดำรงอยู่ได้หากไม่มีความสัมพันธ์กับผู้ใช้เพียงกลุ่มเดียว มีการบังคับใช้ที่ระดับฐานข้อมูล และรับประกันโดยข้อกำหนด on_delete=models.CASCADE : หากอินสแตนซ์ User ถูกลบ Profile ที่เกี่ยวข้องจะถูกลบออก

ฟิลด์อื่นและ __str__(self) ที่เราเคยเห็นมาก่อน เป็นที่น่าสังเกตว่าคุณสามารถเข้าถึงผ่านความสัมพันธ์แบบหนึ่งต่อหนึ่งเพื่อรับแอตทริบิวต์ ในกรณีนี้คือ user.username ในฟังก์ชันของแบบจำลอง

หากต้องการขยายประโยชน์ของความสัมพันธ์ฐานข้อมูล ให้หันมาสนใจที่ Copy from records/models.py :

 from django.db import models class Copy(models.Model): book = models.ForeignKey(Book, on_delete=models.CASCADE) out_to = models.ForeignKey(Patron, blank=True, null=True, on_delete=models.SET_NULL) def __str__(self): has_copy = "checked in" if self.out_to: has_copy = self.out_to.user.username return self.book.title + " -> " + has_copy def check_out(self, p): self.out_to = p self.save() def check_in(self): self.out_to = None self.save()

อีกครั้งที่เราเคยเห็นสิ่งนี้มาก่อนแล้ว ดังนั้นเรามาเน้นที่สิ่งใหม่: models.ForeignKey Copy จะต้องเป็น Book เดียว แต่ห้องสมุดอาจมี Copy หลายฉบับของหนังสือแต่ละ Book Book สามารถมีอยู่ในฐานข้อมูลโดยที่ห้องสมุดไม่มี Copy ในแค็ตตาล็อก แต่ไม่สามารถมี Copy ได้หากไม่มี Book พื้นฐาน

ความสัมพันธ์ที่ซับซ้อนนี้แสดงด้วยบรรทัดต่อไปนี้:

 book = models.ForeignKey(Book, on_delete=models.CASCADE)

พฤติกรรมการลบจะเหมือนกับของ Patron ในการอ้างอิงถึง User

ความสัมพันธ์ระหว่าง Copy และ Patron แตกต่างกันเล็กน้อย สามารถเช็คเอาท์ Copy ได้ถึงหนึ่ง Patron แต่ Patron แต่ละคนสามารถตรวจสอบ Copy ได้มากเท่าที่ห้องสมุดอนุญาต อย่างไรก็ตาม นี่ไม่ใช่ความสัมพันธ์แบบถาวร บางครั้ง Copy จะไม่ถูกเช็คเอาท์ Patron และ Copy มีอยู่อย่างอิสระจากกันในฐานข้อมูล การลบอินสแตนซ์ของอินสแตนซ์หนึ่งไม่ควรลบอินสแตนซ์ของอีกรายการหนึ่ง

ความสัมพันธ์นี้ยังคงเป็นกรณีการใช้งานสำหรับคีย์นอก แต่มีอาร์กิวเมนต์ต่างกัน:

 out_to = models.ForeignKey(Patron, blank=True, null=True, on_delete=models.SET_NULL)

ที่นี่ การมี blank=True อนุญาตให้แบบฟอร์มยอมรับ None เป็นค่าสำหรับความสัมพันธ์ และ null=True อนุญาตให้คอลัมน์สำหรับความสัมพันธ์ของ Patron ในตาราง Copy ในฐานข้อมูลยอมรับ null เป็นค่า พฤติกรรมการลบ ซึ่งจะถูกทริกเกอร์บน Copy หากอินสแตนซ์ของ Patron ถูกลบในขณะที่มีการเช็คเอาท์นั้นคือการตัดความสัมพันธ์ในขณะที่ปล่อยให้ Copy Copy เสียหายโดยการตั้งค่าฟิลด์ Patron เป็นโมฆะ

ประเภทฟิลด์เดียวกัน models.ForeignKey สามารถแสดงความสัมพันธ์ที่แตกต่างกันอย่างมากระหว่างอ็อบเจ็กต์ ความสัมพันธ์เดียวที่ฉันไม่สามารถใส่ในตัวอย่างได้อย่างสมบูรณ์คือเขตข้อมูลแบบกลุ่มต่อกลุ่มซึ่งเหมือนกับเขตข้อมูลแบบหนึ่งต่อหนึ่ง ยกเว้นว่า ตามชื่อที่แนะนำ แต่ละอินสแตนซ์สามารถเชื่อมโยงกับอินสแตนซ์อื่น ๆ ได้มากมาย และแต่ละอื่น ๆ และแต่ละอย่างสามารถเชื่อมโยงกับคนอื่น ๆ ได้มากมายเช่นหนังสือสามารถมีผู้แต่งได้หลายคนซึ่งแต่ละคนได้เขียนหนังสือหลายเล่ม

การย้ายถิ่น

คุณอาจสงสัยว่าฐานข้อมูลรู้ได้อย่างไรว่าแสดงอะไรในตัวแบบ จากประสบการณ์ของผม การอพยพย้ายถิ่นเป็นหนึ่งในสิ่งที่ค่อนข้างตรงไปตรงมา จนกระทั่งไม่เป็นเช่นนั้น แล้วพวกมันก็จะกัดกินหน้าคุณ ต่อไปนี้คือวิธีรักษาแก้วของคุณให้ไม่เสียหาย สำหรับผู้เริ่มต้น: เรียนรู้เกี่ยวกับการย้ายข้อมูลและวิธีโต้ตอบกับสิ่งเหล่านี้ แต่พยายามหลีกเลี่ยงการแก้ไขไฟล์การโยกย้ายด้วยตนเอง หากคุณทราบแล้วว่าคุณกำลังทำอะไรอยู่ ให้ข้ามส่วนนี้และติดตามสิ่งที่เหมาะกับคุณ

ไม่ว่าจะด้วยวิธีใด ให้ตรวจสอบเอกสารอย่างเป็นทางการสำหรับการปฏิบัติต่อบุคคลดังกล่าวอย่างสมบูรณ์

การย้ายข้อมูลแปลการเปลี่ยนแปลงในแบบจำลองเป็นการเปลี่ยนแปลงในสคีมาฐานข้อมูล คุณไม่จำเป็นต้องเขียนมันเอง Django สร้างขึ้นด้วยคำสั่ง python manage.py makemigrations คุณควรเรียกใช้คำสั่งนี้เมื่อคุณสร้างโมเดลใหม่หรือแก้ไขฟิลด์ของโมเดลที่มีอยู่ แต่ไม่จำเป็นต้องทำเช่นนั้นเมื่อสร้างหรือแก้ไขเมธอดของโมเดล สิ่งสำคัญคือต้องสังเกตว่าการโยกย้ายมีอยู่เป็นลูกโซ่ โดยแต่ละอันจะอ้างอิงถึงการโยกย้ายก่อนหน้า เพื่อให้สามารถแก้ไขสคีมาฐานข้อมูลได้โดยปราศจากข้อผิดพลาด ดังนั้น หากคุณกำลังทำงานร่วมกันในโครงการ การรักษาประวัติการย้ายข้อมูลเดียวที่สอดคล้องกันในการควบคุมเวอร์ชันเป็นสิ่งสำคัญ เมื่อมีการโยกย้ายที่ไม่ได้ใช้ ให้เรียกใช้ python manage.py migrate เพื่อปรับใช้ก่อนที่จะเรียกใช้เซิร์ฟเวอร์

ตัวอย่างโปรเจ็กต์ถูกแจกจ่ายด้วยการโยกย้ายเดียว, records/migrations/0001_initial.py อีกครั้ง นี่คือโค้ดที่สร้างโดยอัตโนมัติซึ่งคุณไม่ควรต้องแก้ไข ดังนั้นฉันจะไม่คัดลอกโค้ดในนี้ แต่ถ้าคุณต้องการเข้าใจว่าเกิดอะไรขึ้นเบื้องหลัง ให้ลองดู

การแข่งขัน

ต่างจากการย้ายถิ่น การติดตั้งไม่ใช่ลักษณะทั่วไปของการพัฒนา Django ฉันใช้เพื่อแจกจ่ายข้อมูลตัวอย่างกับบทความ และไม่เคยใช้อย่างอื่นมาก่อน อย่างไรก็ตาม เนื่องจากเราใช้ก่อนหน้านี้ ฉันรู้สึกจำเป็นต้องแนะนำหัวข้อนี้

ครั้งหนึ่ง เอกสารอย่างเป็นทางการค่อนข้างบางในหัวข้อนี้ โดยรวมแล้ว สิ่งที่คุณควรรู้คือโปรแกรมติดตั้งเป็นวิธีการนำเข้าและส่งออกข้อมูลจากฐานข้อมูลของคุณในหลากหลายรูปแบบ รวมถึง JSON ซึ่งเป็นสิ่งที่ฉันใช้ ฟีเจอร์นี้ส่วนใหญ่มีไว้เพื่อช่วยในสิ่งต่างๆ เช่น การทดสอบอัตโนมัติ และไม่ใช่ระบบสำรองหรือวิธีการแก้ไขข้อมูลในฐานข้อมูลแบบสด นอกจากนี้ โปรแกรมติดตั้งจะไม่อัปเดตด้วยการย้ายข้อมูล และหากคุณพยายามใช้โปรแกรมติดตั้งกับฐานข้อมูลที่มีสคีมาที่เข้ากันไม่ได้ โปรแกรมจะล้มเหลว

ในการสร้างโปรแกรมติดตั้งสำหรับฐานข้อมูลทั้งหมด ให้เรียกใช้:

 python manage.py dumpdata --format json > fixture.json

ในการโหลดฟิกซ์เจอร์ ให้รัน:

 python manage.py loaddata fixture.json

บทสรุป

การเขียนโมเดลใน Django เป็นเรื่องใหญ่ และการใช้แผงผู้ดูแลระบบก็เป็นอีกเรื่องหนึ่ง ใน 3,000 คำ ฉันทำได้เพียงแนะนำแต่ละคำเท่านั้น หวังว่าการใช้แผงการดูแลระบบจะช่วยให้คุณมีอินเทอร์เฟซที่ดีขึ้นในการสำรวจว่าแบบจำลองทำงานอย่างไรและสัมพันธ์กันอย่างไร ทำให้คุณมีความมั่นใจในการทดสอบและพัฒนาการแสดงข้อมูลเชิงสัมพันธ์ของคุณเอง

หากคุณกำลังมองหาจุดเริ่มต้นง่ายๆ ให้ลองเพิ่มโมเดล Librarian ที่สืบทอดมาจาก User เหมือนกับ Profile สำหรับความท้าทายที่มากขึ้น ให้ลองใช้ประวัติการชำระเงินสำหรับแต่ละ Copy และ/หรือ Patron (มีหลายวิธีในการทำสิ่งนี้ให้สำเร็จ)

Django Highlights เป็นซีรีส์ที่นำเสนอแนวคิดที่สำคัญของการพัฒนาเว็บใน Django แต่ละบทความเขียนขึ้นเพื่อเป็นแนวทางแบบสแตนด์อโลนในด้านการพัฒนา Django เพื่อช่วยให้นักพัฒนาส่วนหน้าและนักออกแบบเข้าถึงความเข้าใจที่ลึกซึ้งยิ่งขึ้นของ "อีกครึ่งหนึ่ง" ของโค้ดเบส บทความเหล่านี้ส่วนใหญ่สร้างขึ้นเพื่อช่วยให้คุณเข้าใจทฤษฎีและแบบแผน แต่มีตัวอย่างโค้ดบางส่วนที่เขียนใน Django 3.0

อ่านเพิ่มเติม

คุณอาจสนใจบทความและเอกสารต่อไปนี้

  • จุดเด่นของ Django: โมเดลผู้ใช้และการตรวจสอบสิทธิ์ (ตอนที่ 1)
  • ไฮไลท์ของ Django: เทมเพลตบันทึกเส้น (ตอนที่ 2)
  • ไฮไลท์ของ Django: การโต้เถียงเรื่องทรัพย์สินทางปัญญาและไฟล์สื่อ (ตอนที่ 4)
  • เอกสารผู้ดูแลระบบ Django
  • โมเดลจังโก้
  • การอ้างอิงฟิลด์โมเดล Django
  • Django การย้ายถิ่น