Wiskundige modellering in de machinebouw
Modulair en te testen code aanmaken met het Mvc patroon in Python DjangoCity in Italy
Table of Contents
Inleiding tot het Model-View-Controller patroon in Django
Het Model-View-Controller (MVC) patroon is een architectonisch ontwerp dat de test van de tijd heeft gestaan voor het bouwen van webapplicaties die modulair, onderhoudbaar en testbaar zijn. Terwijl Django, het hoog niveau Python web framework, zijn eigen terminologie gebruikt . Modellen, Weergaven en Templates .De onderliggende principes sluiten nauw aan bij MVC. Door te begrijpen hoe deze concepten in kaart te brengen en uit te breiden, kunt u code die gemakkelijker te redeneren over, uit te breiden en valideren door middel van geautomatiseerde tests.
Dit artikel onderzoekt het MVC-patroon in detail, laat zien hoe Django elk onderdeel implementeert en hoe u extra lagen abstractie kunt toepassen om uw codebase schoon en schaalbaar te houden. Wij behandelen best practices voor het organiseren van bedrijfslogica, het schrijven van effectieve tests en het benutten van Django.
Decoderen van de MVC Triade in Django
Het MVC-patroon scheidt een toepassing in drie onderling verbonden componenten:
- Model
- Bekijk . .Behandelt de presentatielogica en gebruikersinterface.
- Controller
Django herinterpreteert deze rollen enigszins. Zijn .Model
Django
Django biedt een krachtig Object-Relational Mapping (ORM) systeem waarmee u datamodellen kunt definiëren als Python-klassen. Elk model kaarten naar een database tabel, en instanties corresponderen met rijen. Door gebruik te maken van Django... kunt u kolommen, relaties (ExtensionKey, ManyToMnyField, OneTooneField) en beperkingen definiëren. De ORM abstracts weg SQL, zodat u Python code voor database operaties kunt schrijven.
Om modellen schoon en gericht te houden, volg deze praktijken:
- Houd de bedrijfslogica uit de modellen indien mogelijk . Modellen moeten in de eerste plaats de gegevensstructuur en relaties definiëren, niet de complexe algoritmen of validatieregels die meerdere entiteiten bestrijken.
- Gebruik modelbeheerders en querysets . . . Gemeenschappelijke query's in te vullen in aangepaste managers. Dit houdt de weergaven mager en bevordert hergebruik.
- Leveringsmodelmethoden voor eenvoudige bewerkingen
- Schrijf migraties voor schemawijzigingen . . . Django
Django-weergaven als controllers
Django views behandelen de controller rol: ze accepteren een HTTP verzoek, uitvoeren noodzakelijke operaties (vaak opvragen van de database via modellen), en een HTTP response. Django ondersteunt twee primaire weergave patronen: functie-gebaseerde views (FBVs) en klasse-gebaseerde views (CBVs).
Function-based views zijn eenvoudig en expliciet. Ze zijn ideaal voor kleine endpoints voor eenmalig gebruik. Echter, naarmate je toepassing groeit, kan je jezelf herhalen code (bijv., het omgaan met paginatie, het opnemen van objecten, of formuliervalidatie).
Op klasse gebaseerde weergaven bieden ingebouwd generiek gedrag voor veelvoorkomende taken (ListView, DetailView, CreateView, etc.). Ze moedigen codehergebruik aan door erfdeel en mixins. Bijvoorbeeld, een ListView behandelt automatisch paginatie, queryset filtering en context rendering. Je kunt methoden als of overschrijven om gedrag aan te passen zonder het herschrijven van boilerplate.
Ongeacht het patroon dat u kiest, houd views dun. Duw bedrijfslogica in servicemodules, formulieren of nutsfuncties. Dit maakt het makkelijker om views te testen en vermindert duplicatie.
Sjablonen als weergaven
Django
Beste praktijken voor templates zijn onder meer:
- Houd logica minimaal ..Sjablonen mogen alleen presentatielogica bevatten (over lijsten heen lopen, elementen onder voorwaarden weergeven). Vermijd Python-niveau bedrijfslogica.
- Gebruik aangepaste sjabloontags en filters
- Sjablonen ordenen door app
Een Modulair Codebase maken met Django Apps
Modulariteit in Django begint met het concept van apps. Elk Django-project kan bestaan uit meerdere zelfstandige apps, elk verantwoordelijk voor een bepaald domein of functie. Bijvoorbeeld, een e-commerce site kan apps voor , , , en hebben. Elke app inkapselt zijn eigen modellen, weergaven, sjablonen, statische bestanden en tests.
Apps modulair houden:
- Bepalen duidelijke grenzen .Een app moet een enkele verantwoordelijkheid en minimale koppeling aan andere apps hebben. Gebruik Django
- Apps herbruikbaar .Maak uw apps zo dat ze kunnen worden uitgepakt en hergebruikt in andere projecten. Dit betekent het vermijden van hardgecodeerde instellingen of directe verwijzingen naar de root-URL's van het project.
- Gebruik afhankelijkheidsinjectie
Afscheiden van de bedrijfslogica: de servicelaag
Een van de meest effectieve manieren om de testbaarheid en modulariteit te verbeteren is het introduceren van een servicelaag. Een servicemodule bevat pure bedrijfslogica, vrij van Django-specifieke verzoek/responsbehandeling. Deze scheiding stelt u in staat om kritische algoritmen te testen zonder een webserver of database te draaien (tenzij nodig voor het aanhouden van gegevens).
Bijvoorbeeld, in plaats van het schrijven van verwerking logica binnen een uitzicht dat een betaling behandelt:
def process_payment(request):
# ... fetch user, order
# ... call Stripe API
# ... update order status
return redirect('success')
U kunt de Stripe interactie verplaatsen naar een service:
# 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
Dan wordt de service alleen maar aangeroepen en wordt de respons behandeld. Deze benadering maakt het eenvoudig om de betalingslogica te testen door externe API's en databasegesprekken te bespotten.
Te testen code in Django schrijven
Testeerbaarheid is een direct voordeel van schone MVC scheiding. Wanneer componenten worden ontkoppeld, kunt u ze in isolatie testen. Django
Modellen voor de test van de eenheid
Modeltests moeten controleren of uw gegevensstructuur en bedrijfsregels (indien deze in het model zijn ingebed) correct werken. Gebruik de klasse en maak modelinstances binnen de testmethoden. Bijvoorbeeld, test dat een model de verwachte string teruggeeft of dat een aangepaste managermethode correct filtert.
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)
Voor meer complexe modellogica, overwegen gebruiken externe afhankelijkheden zoals e-mail verzenden of derden API-gesprekken te vervangen.
Testweergaven (Controllers)
Django
Bij het testen van klasse-gebaseerde weergaven, kunt u direct de weergaveklasse instantiëren (of gebruik maken van de testclient) en beweren op de contextgegevens, statuscodes en redirects. Zorg ervoor dat u zowel gelukkige paden als foutscenario's test (bijv., toestemming geweigerd, vorm validatiefouten).
Testsjablonen
Sjabloon logica kan het best indirect getest worden door middel van view tests die de weergegeven HTML bevatten verwachte elementen. Voor complexe sjabloon tags of filters, schrijf speciale unit tests. Django
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')
Injectie van sokken en afhankelijkheid
Om snel te schrijven, gerichte unit tests, gebruik om externe diensten, database queries, of zelfs Django . ORM te simuleren. Bijvoorbeeld, bij het testen van een dienst die een e-mail stuurt, bespot de functie om daadwerkelijke e-maillevering te vermijden.
Afhankelijkheidsinjectie is een andere techniek: alle afhankelijkheden (databasesessies, externe API's, configuratie) expliciet doorgeven aan uw functies of klasse constructeurs. Dit maakt het gemakkelijk om echte implementaties te vervangen door spotten.
Beste praktijken voor een Clean Django Codebase
Naast de kern MVC-kartering, helpen verschillende technieken om een modulaire en testbare Django-toepassing te behouden:
- Gebruik Django
- Houd URL's schoon . . Organiseer URL-patronen per app, gebruik namespaces en vermijd complexe logica in .
- Levering middleware voor transversale zorgen .Binnenkort is de waarde van middleware goed. Houd middleware lichtgewicht en testbaar.
- Schrijf documentatie en type hints . . . Goed gedocumenteerde code met type annotaties is gemakkelijker te begrijpen en te refactoreren. Gebruik Python
- Doe een consistente coderingsstijl
Real-World Voorbeeld: Bouwen van een Blog met Modular MVC in Django
Laten we de principes toepassen op een eenvoudige blogtoepassing. We zullen een model definiëren, een dienst voor het creëren van berichten met validatie, een klasse-gebaseerde weergave om berichten te tonen en te creëren, en een template met erfenis.
Model (.2]]):
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])
Dienst ():
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
Bekijk ():
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)
Sjabloon ():
{% extends "base.html" %}
{% block content %}
{% for post in post_list %}
{{ post.title }}
{{ post.content|truncatewords:30 }}
{% 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.
Testen van de Blog Service
Hier is een unit test voor de met behulp van spot objecten om database hits te voorkomen (u kunt ook gebruik maken van 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()
Voor meer grondige tests, gebruik Django
Externe aanbevelingen
Om uw begrip van MVC in Django en gerelateerde testpraktijken te verdiepen, verkent u deze bronnen:
- Django Modellaagdocumentatie
- Django klasse-gebaseerde weergaven documentatie . . . Gedetailleerde beschrijving van generieke weergaven en hoe ze aan te passen.
- Django testdocumentatie . . Omvat de testcliënt, testdatabank en geavanceerde technieken.
- Obey the Testing Goat (Test-Driven Web Development with Python) .Een uitstekend boek over TDD met Django dat modulaire vormgeving versterkt.
Conclusie
De implementatie van het MVC-patroon in Django gaat niet over rigide na de tekstboekdefinities, maar over het aannemen van het kernidee van scheiding van zorgen. Door het behandelen van Django... modellen als datarepresentatie, weergaven als controllers en sjablonen als presentatielaag, bouw je natuurlijk een meer modulaire en testbare toepassing... Introductie van een servicelaag maakt de bedrijfslogica verder los, waardoor het eenvoudig is om snelle unittests te schrijven en aan te passen aan veranderende eisen.
Naarmate uw projecten groeien, worden deze principes nog waardevoller. Een goed gestructureerde Django codebase vermindert technische schulden, vereenvoudigt het aan boord krijgen van nieuwe ontwikkelaars, en zorgt ervoor dat uw toepassing kan evolueren zonder cascading breuken. Omarm de geest van MVC, en uw Django toepassingen zullen robuust, onderhoudbaar en klaar zijn voor de uitdagingen van de productie.