คู่มือที่ครอบคลุมเกี่ยวกับการปรับแต่ง Class-Based Generic Views ของ Django เพื่อการพัฒนาเว็บที่มีประสิทธิภาพ เรียนรู้วิธีปรับมุมมองให้ตรงกับความต้องการเฉพาะของคุณ
Django Class-Based Views: การปรับแต่ง Generic View ขั้นสูง
Class-Based Views (CBVs) ของ Django มอบวิธีที่ทรงพลังและนำกลับมาใช้ใหม่ได้ในการสร้างเว็บแอปพลิเคชัน Generic Views ซึ่งเป็นส่วนย่อยของ CBVs นำเสนอโซลูชันสำเร็จรูปสำหรับงานทั่วไป เช่น การแสดงรายการ มุมมองรายละเอียด การสร้าง การอัปเดต และการลบออบเจ็กต์ แม้ว่า Generic Views เหล่านี้จะสะดวกอย่างเหลือเชื่อ แต่ก็มักจะต้องมีการปรับแต่งเพื่อให้เข้ากับความต้องการเฉพาะของแอปพลิเคชันของคุณอย่างสมบูรณ์ คู่มือที่ครอบคลุมนี้สำรวจเทคนิคต่างๆ สำหรับการปรับแต่ง Generic Views ของ Django ช่วยให้คุณสามารถสร้างเว็บแอปพลิเคชันที่มีประสิทธิภาพและบำรุงรักษาได้
ทำความเข้าใจเกี่ยวกับ Class-Based Views ของ Django
ก่อนที่จะเจาะลึกเรื่องการปรับแต่ง ลองทบทวนพื้นฐานของ CBVs และ Generic Views กันก่อน Function-Based Views (FBVs) แบบดั้งเดิมจัดการคำขอ HTTP โดยตรงภายในฟังก์ชันเดียว ในทางกลับกัน CBVs จะจัดระเบียบตรรกะของมุมมองเป็นคลาส ทำให้มีแนวทางที่โครงสร้างดีกว่าและเป็นเชิงวัตถุมากขึ้น สิ่งนี้นำไปสู่การจัดระเบียบโค้ด การนำกลับมาใช้ใหม่ และการทดสอบที่ดีขึ้น
Generic Views คือ CBVs ที่สร้างไว้ล่วงหน้าซึ่งออกแบบมาเพื่อจัดการงานพัฒนาเว็บทั่วไป พวกเขาสืบทอดมาจากคลาสพื้นฐาน เช่น View
และ TemplateView
และนำเสนอฟังก์ชันการทำงานเฉพาะด้าน Generic Views ทั่วไป ได้แก่:
ListView
: แสดงรายการของออบเจ็กต์DetailView
: แสดงรายละเอียดของออบเจ็กต์เดียวCreateView
: จัดการการสร้างออบเจ็กต์โดยใช้ฟอร์มUpdateView
: จัดการการอัปเดตออบเจ็กต์โดยใช้ฟอร์มDeleteView
: จัดการการลบออบเจ็กต์
Generic Views เหล่านี้เป็นรากฐานที่มั่นคง แต่แอปพลิเคชันในโลกแห่งความเป็นจริงมักจะต้องปรับแต่งพฤติกรรมของมัน ลองสำรวจเทคนิคการปรับแต่งต่างๆ
เทคนิคการปรับแต่ง
มีหลายวิธีในการปรับแต่ง Generic Views ของ Django ตั้งแต่การแทนที่คุณลักษณะอย่างง่ายไปจนถึงการแทนที่เมธอดที่ซับซ้อนกว่า เทคนิคที่เหมาะสมขึ้นอยู่กับระดับการปรับแต่งที่จำเป็น
1. การแทนที่คุณลักษณะ
รูปแบบการปรับแต่งที่ง่ายที่สุดคือการแทนที่คุณลักษณะของคลาส Generic View นี่เป็นวิธีที่เหมาะสำหรับการแก้ไขคุณสมบัติพื้นฐาน เช่น โมเดล ชื่อเทมเพลต หรือชื่อออบเจ็กต์บริบท
ตัวอย่าง: การปรับแต่ง ListView
สมมติว่าคุณต้องการแสดงรายการบทความ แต่คุณต้องการใช้เทมเพลตที่กำหนดเองและชื่อออบเจ็กต์บริบทที่แตกต่างกัน
from django.views.generic import ListView
from .models import Article
class ArticleListView(ListView):
model = Article
template_name = 'articles/article_list.html'
context_object_name = 'articles'
def get_queryset(self):
return Article.objects.filter(is_published=True).order_by('-publication_date')
ในตัวอย่างนี้ เราได้แทนที่คุณลักษณะ model
, template_name
และ context_object_name
นอกจากนี้ เรายังได้แทนที่เมธอด get_queryset
เพื่อกรองบทความและเรียงลำดับตามวันที่เผยแพร่ เมธอด get_queryset
ช่วยให้คุณควบคุมออบเจ็กต์ที่จะรวมอยู่ในมุมมองรายการได้ สิ่งนี้มีประโยชน์สำหรับการใช้งานการกรอง การเรียงลำดับ และการแบ่งหน้า
2. การแทนที่เมธอด
การแทนที่เมธอดช่วยให้คุณแก้ไขพฤติกรรมของเมธอดที่มีอยู่ในคลาส Generic View ได้ สิ่งนี้ให้การควบคุมตรรกะของมุมมองมากขึ้น เมธอดทั่วไปที่จะแทนที่ ได้แก่:
get_queryset()
: ควบคุม Queryset ที่ใช้โดยมุมมองget_context_data()
: เพิ่มข้อมูลลงในบริบทของเทมเพลตform_valid()
: จัดการการส่งฟอร์มที่สำเร็จform_invalid()
: จัดการการส่งฟอร์มที่ไม่ถูกต้องget_success_url()
: กำหนด URL ที่จะเปลี่ยนเส้นทางไปหลังจากการส่งฟอร์มสำเร็จget_object()
: ดึงข้อมูลออบเจ็กต์สำหรับ DetailView, UpdateView และ DeleteView
ตัวอย่าง: การปรับแต่ง DetailView
สมมติว่าคุณต้องการแสดงรายละเอียดของบทความ แต่คุณยังต้องการรวมความคิดเห็นที่เกี่ยวข้องในบริบทของเทมเพลต
from django.views.generic import DetailView
from .models import Article, Comment
class ArticleDetailView(DetailView):
model = Article
template_name = 'articles/article_detail.html'
context_object_name = 'article'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['comments'] = Comment.objects.filter(article=self.object, is_approved=True)
return context
ที่นี่ เราได้แทนที่เมธอด get_context_data()
เพื่อเพิ่มตัวแปร comments
ลงในบริบทของเทมเพลต สิ่งนี้ช่วยให้คุณเข้าถึงและแสดงความคิดเห็นที่เกี่ยวข้องในเทมเพลต article_detail.html
ได้อย่างง่ายดาย
3. การใช้ Mixins
Mixins คือคลาสที่นำกลับมาใช้ใหม่ได้ซึ่งมีฟังก์ชันการทำงานเฉพาะ พวกเขาสามารถรวมกับ Generic Views เพื่อเพิ่มคุณสมบัติโดยไม่ต้องแก้ไขตรรกะหลักของมุมมอง Django มี Mixins ในตัวหลายรายการ และคุณยังสามารถสร้างของคุณเองได้
ตัวอย่าง: การใช้ LoginRequiredMixin
LoginRequiredMixin
ช่วยให้มั่นใจได้ว่าเฉพาะผู้ใช้ที่เข้าสู่ระบบเท่านั้นที่จะสามารถเข้าถึงมุมมองเฉพาะได้
from django.views.generic import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
form_class = ArticleForm
template_name = 'articles/article_form.html'
success_url = '/articles/' # แทนที่ด้วย URL ที่สำเร็จที่คุณต้องการ
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
ในตัวอย่างนี้ เราได้ใช้ LoginRequiredMixin
เพื่อจำกัดการเข้าถึง ArticleCreateView
ให้กับผู้ใช้ที่เข้าสู่ระบบ นอกจากนี้ เรายังได้แทนที่เมธอด form_valid
เพื่อตั้งค่าผู้เขียนบทความเป็นผู้ใช้ปัจจุบันโดยอัตโนมัติ นี่แสดงให้เห็นว่า Mixins สามารถรวมกับการแทนที่เมธอดเพื่อปรับแต่งที่ซับซ้อนได้อย่างไร
การสร้าง Mixins ที่กำหนดเอง
คุณยังสามารถสร้าง Mixins ของคุณเองเพื่อสรุปตรรกะที่นำกลับมาใช้ใหม่ได้ ตัวอย่างเช่น คุณอาจสร้าง Mixin ที่ตั้งค่าผู้ใช้ปัจจุบันเป็นผู้เขียนของอินสแตนซ์โมเดลโดยอัตโนมัติ หรือ Mixin ที่จัดการการตรวจสอบสิทธิ์
from django.contrib.auth.mixins import UserPassesTestMixin
class AuthorRequiredMixin(UserPassesTestMixin):
def test_func(self):
return self.request.user.is_staff or (self.request.user == self.get_object().author)
def handle_no_permission(self):
# แทนที่ด้วยการเปลี่ยนเส้นทางหรือการจัดการข้อผิดพลาดที่คุณต้องการ
return redirect('permission_denied') # หรือยกเว้นข้อยกเว้น
AuthorRequiredMixin
นี้อนุญาตให้เข้าถึงได้เฉพาะสมาชิกของเจ้าหน้าที่หรือผู้เขียนออบเจ็กต์เท่านั้น คุณสามารถใช้ Mixin นี้กับ UpdateView
หรือ DeleteView
เพื่อให้แน่ใจว่าเฉพาะผู้ใช้ที่ได้รับอนุญาตเท่านั้นที่สามารถแก้ไขหรือลบออบเจ็กต์ได้
4. การปรับแต่งเทมเพลต
แม้ว่าเทคนิคข้างต้นจะมุ่งเน้นไปที่การแก้ไขตรรกะของมุมมอง แต่การปรับแต่งเทมเพลตเป็นสิ่งสำคัญสำหรับการควบคุมการนำเสนอข้อมูล Generic Views ใช้เทมเพลตเพื่อแสดงผลลัพธ์ HTML คุณสามารถปรับแต่งเทมเพลตเหล่านี้ให้ตรงกับการออกแบบและการสร้างแบรนด์ของแอปพลิเคชันของคุณได้
แบบแผนการตั้งชื่อเทมเพลต
Generic Views ทำตามแบบแผนการตั้งชื่อเทมเพลตที่เฉพาะเจาะจง ตัวอย่างเช่น:
ListView
:<app_name>/<model_name>_list.html
(เช่นarticles/article_list.html
)DetailView
:<app_name>/<model_name>_detail.html
(เช่นarticles/article_detail.html
)CreateView
/UpdateView
:<app_name>/<model_name>_form.html
(เช่นarticles/article_form.html
)DeleteView
:<app_name>/<model_name>_confirm_delete.html
(เช่นarticles/article_confirm_delete.html
)
คุณสามารถแทนที่คุณลักษณะ template_name
ในคลาส View เพื่อใช้เทมเพลตอื่นได้ ภายในเทมเพลต คุณสามารถเข้าถึงข้อมูลที่มุมมองจัดเตรียมให้ผ่านทางออบเจ็กต์บริบท ชื่อออบเจ็กต์บริบทเริ่มต้นมักจะเป็นเวอร์ชันตัวพิมพ์เล็กของชื่อโมเดล (เช่น article
สำหรับ Article
) คุณสามารถเปลี่ยนสิ่งนี้ได้โดยใช้คุณลักษณะ context_object_name
ตัวอย่าง: การปรับแต่งเทมเพลต ListView
ในเทมเพลต articles/article_list.html
คุณสามารถวนซ้ำตัวแปรบริบท articles
(ตามที่กำหนดไว้ในตัวอย่าง ArticleListView
ด้านบน) เพื่อแสดงรายการบทความ
<h1>บทความ</h1>
<ul>
{% for article in articles %}
<li><a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a></li>
{% endfor %}
</ul>
5. การปรับแต่งฟอร์ม (CreateView & UpdateView)
CreateView
และ UpdateView
อาศัยฟอร์ม Django เพื่อจัดการอินพุตของผู้ใช้ การปรับแต่งฟอร์มเหล่านี้ช่วยให้คุณควบคุมฟิลด์ที่แสดง กฎการตรวจสอบ และลักษณะที่ปรากฏ
การใช้ form_class
คุณสามารถระบุคลาสฟอร์มที่จะใช้กับคุณลักษณะ form_class
ในคลาส View หากคุณไม่ได้ระบุคลาสฟอร์ม Django จะสร้าง ModelForm
โดยอัตโนมัติตามโมเดลที่เกี่ยวข้องกับมุมมอง
การแทนที่เมธอดของฟอร์ม
คุณสามารถแทนที่เมธอดในคลาสฟอร์มของคุณเพื่อปรับแต่งพฤติกรรม เมธอดทั่วไปที่จะแทนที่ ได้แก่:
__init__()
: เริ่มต้นฟอร์มและแก้ไขฟิลด์clean()
: ทำการตรวจสอบที่กำหนดเองในหลายฟิลด์clean_<field_name>()
: ทำการตรวจสอบที่กำหนดเองสำหรับฟิลด์เฉพาะ
ตัวอย่าง: การปรับแต่งฟอร์มบทความ
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'is_published']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['content'].widget = forms.Textarea(attrs={'rows': 5})
def clean_title(self):
title = self.cleaned_data['title']
if len(title) < 5:
raise forms.ValidationError("Title must be at least 5 characters long.")
return title
ในตัวอย่างนี้ เราได้ปรับแต่ง ArticleForm
โดยการตั้งค่าคุณลักษณะ fields
ในคลาส Meta
เพื่อระบุว่าควรมีฟิลด์ใดอยู่ในฟอร์ม นอกจากนี้ เรายังได้แทนที่เมธอด __init__()
เพื่อปรับแต่งวิดเจ็ตของฟิลด์ content
และเมธอด clean_title()
เพื่อเพิ่มการตรวจสอบที่กำหนดเองสำหรับฟิลด์ title
6. การจัดการฟอร์มแบบไดนามิก
บางครั้งคุณต้องปรับฟอร์มแบบไดนามิกตามผู้ใช้หรือปัจจัยอื่น ๆ คุณสามารถทำได้โดยการแทนที่เมธอด get_form_kwargs()
ในคลาส View เมธอดนี้ช่วยให้คุณส่งอาร์กิวเมนต์คำหลักเพิ่มเติมไปยังตัวสร้างของฟอร์มได้
ตัวอย่าง: การส่งผู้ใช้ไปยังฟอร์ม
from django.views.generic import CreateView
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(CreateView):
model = Article
form_class = ArticleForm
template_name = 'articles/article_form.html'
success_url = '/articles/' # แทนที่ด้วย URL ที่สำเร็จที่คุณต้องการ
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
จากนั้น ใน ArticleForm
ของคุณ คุณสามารถเข้าถึงผู้ใช้ผ่านอาร์กิวเมนต์คำหลัก user
ในเมธอด __init__()
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'is_published']
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if self.user and not self.user.is_staff:
del self.fields['is_published'] # เฉพาะเจ้าหน้าที่เท่านั้นที่สามารถเผยแพร่ได้
ในตัวอย่างนี้ เรากำลังส่งผู้ใช้ปัจจุบันไปยังฟอร์มและลบฟิลด์ is_published
แบบไดนามิกหากผู้ใช้ไม่ได้เป็นสมาชิกของเจ้าหน้าที่ นี่แสดงให้เห็นว่าคุณสามารถปรับฟอร์มแบบไดนามิกตามสิทธิ์ของผู้ใช้อย่างไร
การปรับแต่งขั้นสูง: การใช้ Viewsets
สำหรับแอปพลิเคชันที่ซับซ้อนมากขึ้น โดยเฉพาะอย่างยิ่งแอปพลิเคชันที่เกี่ยวข้องกับ APIs ให้พิจารณาใช้ ViewSets ของ Django REST Framework (DRF) ViewSets รวมมุมมองที่เกี่ยวข้อง (เช่น รายการ สร้าง ดึงข้อมูล อัปเดต ลบ) เป็นคลาสเดียว ทำให้มีวิธีที่สะอาดกว่าและเป็นระเบียบมากขึ้นในการจัดการ API endpoints
ตัวอย่าง: การสร้าง ArticleViewSet
from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
ArticleViewSet
ที่เรียบง่ายนี้มีฟังก์ชันการทำงาน CRUD (สร้าง อ่าน อัปเดต ลบ) มาตรฐานทั้งหมดสำหรับบทความ คุณสามารถปรับแต่ง ViewSets โดยใช้เทคนิคที่คล้ายคลึงกันกับ Generic Views เช่น การแทนที่เมธอด เช่น get_queryset()
, perform_create()
และ perform_update()
ข้อควรพิจารณาเพิ่มเติมสำหรับการปรับแต่ง Generic View
เมื่อปรับแต่ง Generic View สำหรับผู้ใช้งานทั่วโลก โปรดคำนึงถึงข้อควรพิจารณาต่อไปนี้:
- การแปลเป็นภาษาท้องถิ่นและการทำให้เป็นสากล (L10n/I18n): ตรวจสอบให้แน่ใจว่าเทมเพลตและแบบฟอร์มของคุณรองรับหลายภาษาและรูปแบบระดับภูมิภาค ใช้คุณสมบัติ i18n/l10n ที่มีอยู่ภายในของ Django
- เขตเวลา: จัดการการแปลงเขตเวลาอย่างถูกต้องเพื่อแสดงวันที่และเวลาในเวลาท้องถิ่นของผู้ใช้ ใช้โมดูล
timezone
ของ Django - การจัดรูปแบบสกุลเงิน: จัดรูปแบบค่าสกุลเงินให้เหมาะสมสำหรับภูมิภาคต่างๆ พิจารณาใช้ไลบรารีเช่น
babel
สำหรับการจัดรูปแบบสกุลเงิน - การจัดรูปแบบวันที่และตัวเลข: ใช้รูปแบบวันที่และตัวเลขที่เหมาะสมตามสถานที่ของผู้ใช้
- การเข้าถึง: ตรวจสอบให้แน่ใจว่ามุมมองและเทมเพลตที่ปรับแต่งของคุณสามารถเข้าถึงได้สำหรับผู้ใช้ที่มีความพิการ ทำตามหลักเกณฑ์การเข้าถึง เช่น WCAG
- การออกแบบที่ตอบสนอง: ตรวจสอบให้แน่ใจว่าเทมเพลตของคุณตอบสนองและปรับให้เข้ากับขนาดหน้าจอและอุปกรณ์ต่างๆ ที่ผู้ใช้ทั่วโลกใช้
- ความละเอียดอ่อนทางวัฒนธรรม: ระลึกถึงความแตกต่างทางวัฒนธรรมเมื่อออกแบบมุมมองและเทมเพลตของคุณ หลีกเลี่ยงการใช้รูปภาพหรือภาษาที่อาจเป็นที่ขัดแย้งต่อบางวัฒนธรรม ตัวอย่างเช่น สมาคมสีและสัญลักษณ์อาจมีความหมายที่แตกต่างกันมากในแต่ละวัฒนธรรม
ตัวอย่าง: การจัดการเขตเวลา
หากต้องการแสดงวันที่เผยแพร่ในเขตเวลาท้องถิ่นของผู้ใช้ คุณสามารถใช้แท็ก timezone
ในเทมเพลตของคุณได้:
{% load tz %}
<p>เผยแพร่เมื่อ: {% timezone article.publication_date %}</p>
ตรวจสอบให้แน่ใจว่าคุณมี USE_TZ = True
ในไฟล์การตั้งค่า Django ของคุณ
แนวทางปฏิบัติที่ดีที่สุดสำหรับการปรับแต่ง Generic View
ปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดเหล่านี้เพื่อให้แน่ใจว่าการปรับแต่งของคุณสามารถบำรุงรักษาและมีประสิทธิภาพ:
- ทำให้เรียบง่าย: หลีกเลี่ยงการทำให้การปรับแต่งของคุณซับซ้อนเกินไป ใช้เทคนิคที่ง่ายที่สุดที่บรรลุผลลัพธ์ที่ต้องการ
- จัดทำเอกสารโค้ดของคุณ: เพิ่มความคิดเห็นเพื่ออธิบายการปรับแต่งของคุณและเหตุผลที่จำเป็น
- ทดสอบอย่างละเอียด: เขียน Unit Tests เพื่อให้แน่ใจว่าการปรับแต่งของคุณทำงานอย่างถูกต้อง
- ใช้ Mixins อย่างชาญฉลาด: สร้าง Mixins ที่นำกลับมาใช้ใหม่ได้เพื่อสรุปฟังก์ชันการทำงานทั่วไป
- ทำตามแบบแผนของ Django: ปฏิบัติตามสไตล์การเขียนโค้ดและแบบแผนการตั้งชื่อของ Django
- พิจารณาความปลอดภัย: ตระหนักถึงช่องโหว่ด้านความปลอดภัยที่อาจเกิดขึ้นเมื่อปรับแต่งมุมมอง ล้างข้อมูลอินพุตของผู้ใช้และป้องกันการโจมตีทั่วไป เช่น Cross-Site Scripting (XSS) และ SQL Injection
สรุป
Class-Based Generic Views ของ Django มอบวิธีที่ทรงพลังและยืดหยุ่นในการสร้างเว็บแอปพลิเคชัน ด้วยการเรียนรู้เทคนิคการปรับแต่งที่ระบุไว้ในคู่มือนี้ คุณสามารถปรับแต่ง Generic Views ให้ตรงกับความต้องการเฉพาะของคุณ สร้างเว็บแอปพลิเคชันที่มีประสิทธิภาพ บำรุงรักษาได้ และเข้าถึงได้ทั่วโลก ตั้งแต่การแทนที่คุณลักษณะอย่างง่ายไปจนถึงการแทนที่เมธอดที่ซับซ้อนและการใช้ Mixin ความเป็นไปได้นั้นมีมากมาย อย่าลืมพิจารณามุมมองระดับโลกและแนวทางปฏิบัติที่ดีที่สุดเพื่อให้แน่ใจว่าแอปพลิเคชันของคุณตอบสนองต่อผู้ใช้งานจากนานาชาติที่หลากหลาย