מבוא לדגם-View-Controller Pattern ב Django

תבנית מודל-View-Controller (MVC) היא עיצוב אדריכלי שעמד במבחן הזמן לבניית יישומי אינטרנט מודולריים, מקיפים, וניתן לבדיקה. בעוד Django, מסגרת האינטרנט של Python ברמה גבוהה, משתמשת במינוי שלה - מודלים, תצוגות, תבניות - עקרונות הבסיס תואמים הדוק עם MVC.

מאמר זה חוקר את תבנית MVC בעומק, מראה כיצד Django מיישמת כל רכיב וכיצד ניתן ליישם שכבות נוספות של מופשט כדי לשמור על בסיס קוד שלך נקי והיקף.We יכסה את השיטות הטובות ביותר עבור ארגון לוגיקה עסקית, כתיבה בדיקות יעילות, ומינוף הכלים המובנים של Django כדי לאכוף הפרדה של חששות.

ירידה ב- MVC Triad ב- Django

תבנית MVC מפרידה יישום לשלושה מרכיבים קשורים:

  • (ב) ,0)ModelcioFLT:1 - ניהול נתונים ולוגיקה עסקית.
  • (ב) ,0)ViewofLT:1 - Handles theמצגת Logic and User Interface.
  • (ב) ,0) ,ControllereurFLT:1 - מעבד את קלט המשתמשים ואת לתאם בין מודל ותצוגה.

Django reinterprets תפקידים אלה מעט.הModel מתאים ישירות למודל MVC.The "View" ב Django פועל כבקר - הוא מקבל בקשות HTTP, שאילתות המודל, וחוזר תגובה. "Template" משמש כ- MVC View, עריכת HTML (או פורמטים אחרים פלט) עבור הלקוח.

מודל מודל של Django

Django מספק מערכת ניהול אובייקטים רבת עוצמה (ORM) המאפשרת לך להגדיר מודלים נתונים כמו כיתות פייתון.כל מודל מפות בטבלה מסד נתונים, ומקרים מתאימים לשורה.על ידי שימוש בשדות המודל של Django, באפשרותך להגדיר עמודות, מערכות יחסים (ForignKey, ManyTo ManyField, OneTo OneField), ו-ORMs מופשטים לקודמת קודים, כדי לכתוב קידוד SQL.

כדי לשמור על מודלים נקיים וממוקדים, בצעו את הפעולות האלה:

  • (FLT:0) לשמור על לוגיקה עסקית מתוך מודלים כאשר ניתן לאלף 1) מודלים צריכים להגדיר בעיקר מבנה נתונים ומערכות יחסים, לא אלגוריתמים מורכבים או כללי אימות המשתרעים על פני מספר גופים.
  • (FLT:0) מנהלי מודל ושאילתות של מודל (Use Model Manager andשאsetsetsFIRLT:1) - לוכדים שאילתות נפוצות למנהלים מותאמים אישית.
  • (ב) שיטות מודל למינוף של פעולות פשוטות (FLT:0) שיטות כמו FLT:0 או חישוב נכס מקובלות, אך נמנעים מלוגיקה כבדה המתקשרת עם מודלים אחרים.
  • (FLT:0Write Migrations for schema ChangesveFLT:1) - מערכת ההגירה של דינגו עוקב אחר שינויים ומאפשרת פריסה בטוחה על פני סביבות.

⁇ ⁇ ⁇

תצוגות Django מטפלות בתפקיד הבקר: הם מקבלים בקשה HTTP, מבצעים פעולות הכרחיות (לעתים קרובות שאילתת מסד הנתונים באמצעות מודלים), והחזרת תגובה HTTP. Django תומך בשני דפוסי תצוגה עיקריים: השקפות המבוססות על תפקוד (FBVs) והשקפות מבוססות מעמד (CBVs).

(FLT:0Function-based ViewssFLT:1 הם פשוטים ומפורטים.הם אידיאליים עבור נקודות קצה קטנות, חד-תכליתיות.עם זאת, ככל שהיישום שלך גדל, ייתכן שתמצא את עצמך חוזר על קוד (למשל, טיפול בדמיון, רישום אובייקטים או טופס אימות).

(הופנה מהדף ⁇ ) ,0) , השקפה מבוססת-קלאסית (ListView, diView, CreateView וכו ') הם מעודדים את הקוד לשימוש מחדש באמצעות ירושה ומיקסינים.לדוגמה, רשימת הצג מטפל באופן אוטומטי בדמיון, סינון שאילתה והקשר של שיטות כמו: FLT או LT:2 כדי להתאים אישית התנהגות ללא סוללת.

ללא קשר לתבנית שתבחר, שמור על נופים דקים. Push Business Logic לתוך מודולים שירות, טפסים או פונקציות שירות.זה הופך את ההשקפות לקלות יותר לבדיקה ולהפחית את השכפול.

תבניות כמראות

מנוע התבנית של דנגו הופך את HTML על ידי שילוב של סימון סטטי עם משתנים בהקשר דינמי.תבניות מעצבות את שכבת המצגת (ה"View" במערכת הירושה של Django מאפשר לך ליצור השלד בסיסי ולהרחיב אותו בתבניות ילדים, צמצום ריצוף ופשט שינויים פריסה.

שיטות הטובות ביותר לתבניות כוללות:

  • (FLT:0) שמור על לוגיקה מינימליתFLT:1 - תבניות צריכות להכיל רק לוגיקה מצגת (מעל רשימות, אלמנטים המציגים באופן תנאי).
  • (FLT:0) תגי תבנית מותאמות אישית ופילטרים של ההרחבה 1) - עבור פורמט מורכב או רכיבי UI הניתנים לחזרה, ליצור תגים או מסננים משלך ולא להציב לוגיקה בתבנית.
  • (ב) ,0) ,[[1924]]]], [[1924]]]]]], [[1924]]]]]], [[1924]]]]]], [[1924]]]]]]]], [[1924]]]]]]

יצירת קוד מודולרי עם Django Apps

המודולריות ב-Django מתחילה עם הרעיון של יישומים.כל פרויקט Django יכול לכלול יישומים רבים המכילים את עצמם, כל אחד אחראי על תחום או תכונה ייחודית.לדוגמה, אתר מסחר אלקטרוני עשוי להיות יישומים עבור FLT:4, ;5, FLT:6, FLT:6 ו-FLT 7 כל אפליקציה מעצימה את המודלים שלה, ההשקפות, תבניות, , מבחנים סטטיים, ומבחנים.

כדי לשמור על יישומים באמת מודולרי:

  • (FLT:0)Define בהיר גבולות ברורים (FLT:1) - אפליקציה צריכה להיות אחריות אחת וניתוק מינימלי לאפליקציות אחרות. השתמש באות של Django או במודע ביניים מותאם אישית כדי לתקשר בין יישומים ללא היבוא הדוק.
  • (FLT:0) יישומים הניתנים לחזרה (Reusable ApplicationsFLT:1) - עיצוב היישומים שלך כך שניתן יהיה לחלץ אותם ולהשתמש בהם מחדש בפרויקטים אחרים.זה אומר הימנעות מהגדרות קודמות קשות או אזכורים ישירים ל-URL השורשי של הפרויקט.
  • (FLT:0) הזרקת התלות של הזרקה 1:1 - כאשר אפליקציה זקוקה למשהו מאפליקציית אחרת, להעביר אותו כפרמטר או להשתמש בשכבה שירות שניתן ללעג במבחנים.

המונחים: the Service Layer

אחת הדרכים היעילות ביותר לשיפור יכולת הבדיקה והמודולריות היא להציג שכבת שירות.מודול שירות מכיל לוגיקה עסקית טהורה, ללא תשלום מטיפול ספציפי ב-Django.הפרדה זו מאפשרת לך לבחון אלגוריתמים קריטיים מבלי לנסח שרת אינטרנט או מסד נתונים (אלא אם כן נדרש עבור עקשנות נתונים).

לדוגמה, במקום לכתוב לוגיקה עיבוד בתוך תפיסה שמטפלת בתשלום:

def process_payment(request):
 # ... fetch user, order
 # ... call Stripe API
 # ... update order status
 return redirect('success')

ניתן להעביר את האינטראקציה של הרצועה לשירות:

# services/payment_service.py
class PaymentService:
 def process(self, user, order, payment_info):
 # Stripe API calls, business rules, etc.
 # Return result and possibly new order status
 pass

אז הנוף קורא רק לשירות ומטפלים בתגובה.גישה זו הופכת אותו פשוט לבחינת לוגיקה התשלום על ידי לעג ל API חיצוני ושיחות מסד נתונים.

קוד מבחן ב Django

מבחן הוא היתרון הישיר של הפרדה MVC נקייה.כאשר מרכיבים מסולקים, אתה יכול לבדוק אותם בבידוד. מסגרת הניסוי הבנויה של דנגו (מבוסס על 10-10 של Python) מספק כלים ליצירת בדיקות עבור מודלים, תצוגות, תבניות וצורות.בנוסף, ספריות צד שלישי כמו FLT:11 מציעים יותר מס סינכר ותיקון חזק.

יחידת בדיקות מודלים

בדיקות מודל צריכות לאמת כי מבנה הנתונים שלך ואת כללי העסק (אם כל מה שרשום במודל) עובד נכון. השתמש בכיתת ה- 12 של ההרחבה וליצור מקרים מודל בשיטות הבדיקה.לדוגמה, לבדוק כי שיטת מודל (FLT:13) מחזירה את המחרוזת הצפויה, או ששיטת מנהל מותאם אישית מסננים כראוי.

from django.test import TestCase
from .models import Product

class ProductModelTest(TestCase):
 def test_string_representation(self):
 product = Product(name='Test Product')
 self.assertEqual(str(product), product.name)

עבור יותר מורכב מודל לוגיקה, לשקול שימוש ב-FLT:15 להחליף תלות חיצונית כמו שליחת דואר אלקטרוני או שיחות API של צד שלישי.

בדיקה (Controllers)

לקוח המבחן של דאנגגו מאפשר לך לדמות בקשות HTTP ולבחון תשובות.זה אידיאלי עבור בדיקות אינטגרציה לבדוק routing, אימות, ותבנית עריכת.עם זאת, עבור יחידה לבדיקת ההיגיון בתוך תצוגות, עליך להפריד את ההיגיון הזה לשירותים או מודולים אחרים.

כאשר בוחנים תצוגות מבוססות מעמד, אתה יכול מידל את שיעור התצוגה ישירות (או להשתמש בלקוח המבחן) ולקבוע על נתוני ההקשר, קודי הסטטוס והפניות.לוודא שאתה בודק הן נתיבים מאושרים והן תרחישים שגיאה (למשל, הרשאות הכחישו, טופס שגיאות אימות).

תבניות

לוגיקה של תבנית היא הטובה ביותר נבדקת בעקיפין באמצעות בדיקות ראייה כי בדיקת ה-HTML מוצפנת מכילה אלמנטים צפויים. עבור תגים מורכבים של תבניות או מסננים, לכתוב בדיקות יחידות ייעודיות.Django'sFLT:16 ו-FLT:17 שיעורים לתת לך להפוך מחרוזת תבנית וטוען על הפלט.

from django.template import Template, Context
from django.test import TestCase

class CustomTagTest(TestCase):
 def test_uppercase_filter(self):
 t = Template('{% load my_filters %}{{ value|my_upper }}')
 c = Context({'value': 'hello'})
 self.assertEqual(t.render(c), 'HELLO')

פיזור ונפיחות

כדי לכתוב בדיקות יחידה מהירות וממוקדות, השתמש ב-FLT:19 כדי לדמות שירותים חיצוניים, שאילתות מסד נתונים, או אפילו Django של ORM.לדוגמה, כאשר בודקים שירות שולח דואר אלקטרוני, ללעג את הפונקציה של FLT:20 כדי למנוע משלוח דואר אלקטרוני בפועל.

הזרקת התלות היא טכניקה נוספת: להעביר את כל התלויים (פגישות בסיס נתונים, API חיצוני, תצורה) במפורש לפונקציות או לבונים בכיתה שלך.זה הופך את זה קל להחליף יישום אמיתי עם לעג.

שיטות טובות עבור קוד Django נקי

מעבר למיפוי הליבה MVC, מספר טכניקות מסייעות לשמור על יישום Django מודולרי ומבחן:

  • (ב) ויקרא י"א: ויקרא י"ד: ויקרא י"ד: ויקרא י"ד, ויקרא י"א)
  • (ב) [ה]:0] לשמור על כתובת האתר נקיה (=ה) 1 (הופנה מהדף ארגן תבניות לאפליקציות, להשתמש בשם "מרחבי שם" ולהימנע מנטילת לוגיקה מורכבת ב-FLT:21).
  • (ב) [15] מדרש (ב) , ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
  • (ב) ,0) ,Write תיעוד ורמזים מסוג זה (FLT:1) , קוד טוב עם סטיות מסוג זה קל יותר להבין ולייצר מחדש את השימוש במודול ה-FLT:22 של Python, ולשקול כלים כמו FLT:23 לניתוח סטטי.
  • (FLT:0) Adopt סגנון עקבי של קידוד 1 ( Follow PEP 8, השתמש linters (flake8, pylint) ופורמטים (שחור, isort) זה מפחית עומס קוגניטיבי והופך את ביקורות קוד חלקה יותר.

דוגמה אמיתית לעולם: בניית בלוג עם Modular MVC ב Django

בואו ליישם את העקרונות ליישום בלוג פשוט.We'll להגדיר מודל ; a Service ליצירת פוסטים עם אימות, תצוגה מבוססת כיתה רשימה וליצור פוסטים, ותבנית עם ירושה.

(ב) ויקרא י"ד): "ה' (בראשית י"ד):

from django.db import models
from django.urls import reverse

class Post(models.Model):
 title = models.CharField(max_length=200)
 content = models.TextField()
 published = models.BooleanField(default=False)
 created_at = models.DateTimeField(auto_now_add=True)

 def get_absolute_url(self):
 return reverse('post_detail', args=[self.pk])

(ב) ויקרא י"ד):

from .models import Post

class PostService:
 def create_post(self, title, content, user):
 # business logic: check permissions, validate content length, etc.
 if len(content) < 50:
 raise ValueError("Content must be at least 50 characters.")
 post = Post.objects.create(title=title, content=content, author=user)
 return post

(ב) ויקרא י"ד):

from django.views.generic import ListView, CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from .services import PostService
from .models import Post

class PostListView(ListView):
 model = Post
 template_name = 'blog/post_list.html'
 queryset = Post.objects.filter(published=True)

class PostCreateView(LoginRequiredMixin, CreateView):
 model = Post
 fields = ['title', 'content']
 template_name = 'blog/post_form.html'

 def form_valid(self, form):
 # Use service to enforce additional rules
 service = PostService()
 try:
 post = service.create_post(
 title=form.cleaned_data['title'],
 content=form.cleaned_data['content'],
 user=self.request.user
 )
 except ValueError as e:
 form.add_error(None, str(e))
 return self.form_invalid(form)
 return super().form_valid(form)

(ב) ויקרא י"ד): "ה' (בראשית כ"ד):

{% extends "base.html" %}
{% block content %}
 {% for post in post_list %}
 
 {% endfor %}
{% endblock %}

This structure keeps the view lean, the model focused, and the business logic isolated in a service that can be unit-tested easily.

בדיקת שירות בלוג

הנה מבחן יחידה עבור FLT:33 שימוש באובייקטים ללעג כדי למנוע פגיעה במסד הנתונים (אפשר גם להשתמש מסד הנתונים של Django לאינטגרציה):

from django.test import TestCase
from unittest.mock import patch, MagicMock
from .services import PostService

class PostServiceTest(TestCase):
 @patch('blog.services.Post.objects.create')
 def test_create_post_short_content_raises_error(self, mock_create):
 service = PostService()
 with self.assertRaises(ValueError):
 service.create_post("Title", "Short", mock_some_user)
 mock_create.assert_not_called()

לצורך בדיקות מעמיקות יותר, השתמש ב-Django'sFLT:35 ובמסד הנתונים האמיתי כדי לוודא כי למעשה להציל את הפוסט וכי שדה המחבר מוגדר כראוי.

המלצות חיצוניות

כדי להעמיק את ההבנה של MVC ב Django ובדיקות הקשורות, לחקור את המשאבים האלה:

  • (ב) ,0) ,Django Model Documents: FLT:1, מדריך רשמי על מודלים, שדות ומערכות יחסים.
  • (ב) [ה]:0] ,(Django class-based Views: איור מפורט של השקפות גנריות וכיצד להתאים אותן.
  • (FLT:0)Django בודק תיעוד של תיעוד של ההרחבה 1:1 - מכסה את הלקוח המבחן, מסד הנתונים של הבדיקה, וטכניקות מתקדמות.
  • (FLT:0)Obey the Testing Goat (Test-Driven Web Development with Python)cioFLT:1 - ספר מעולה על TDD עם Django אשר מחזק עיצוב מודולרי.

מסקנה

יישום דפוס MVC ב Django אינו על נוקשות לאחר הגדרות לימוד, אלא על אימוץ הרעיון הליבה של הפרדה של חששות. על ידי טיפול במודלים של Django כייצוג נתונים, תצוגות כבקרים, ותבניות כמו שכבת המצגת, אתה בונה באופן טבעי יישום מודולרי יותר ומבחן.

ככל שהפרויקטים שלך גדלים, עקרונות אלה הופכים אפילו יותר יקר.בסיס קוד Django בנוי היטב מקטין את החוב הטכני, מפשט על סקייטבורד עבור מפתחים חדשים, ומבטיח כי היישום שלך יכול להתפתח ללא הפסקות מרתיעות.