Naučite se učinkovito organizirati svoje API-je Django REST Framework z uporabo ViewSets. Ta vodnik zajema vse od osnovne uporabe do napredne prilagoditve, s praktičnimi primeri.
Django REST Framework ViewSets: Obvladovanje Organizacije API Končnih Točk
V sodobnem spletnem razvoju je gradnja robustnih in dobro strukturiranih API-jev ključnega pomena. Django REST Framework (DRF) je zmogljiv nabor orodij za ustvarjanje RESTful API-jev z Djangom. Medtem ko DRF ponuja različna orodja za ustvarjanje API končnih točk, ViewSets zagotavljajo eleganten način za organizacijo povezanih pogledov v en sam razred, kar vodi do čistejše in bolj vzdrževane kode. Ta obsežen vodnik bo podrobno raziskal ViewSets, zajel njihove prednosti, uporabo in napredne tehnike prilagajanja.
Kaj so ViewSets?
ViewSet je pogled, ki temelji na razredu in zagotavlja implementacije za standardne operacije, kot so list
, create
, retrieve
, update
in destroy
. Namesto definiranja ločenih pogledov za vsako operacijo,ViewSet združuje te operacije v en sam razred, kar poenostavlja strukturo API-ja in zmanjšuje podvajanje kode. ViewSets so še posebej uporabni pri delu z API-ji, ki temeljijo na modelih, kjer so te standardne operacije pogosto potrebne. Mislite na ViewSet kot na logično skupino operacij na določenem viru.
Prednosti uporabe ViewSets
- Ponovna uporaba kode: ViewSets spodbujajo ponovno uporabo kode z enkapsulacijo običajne logike API-ja v en sam razred. To zmanjšuje odvečnost in olajša vzdrževanje kode.
- Poenostavljeno usmerjanje: ViewSets poenostavljajo usmerjanje z združevanjem povezanih pogledov pod enim URL prefiksom. To vodi do čistejše in bolj organizirane URL strukture.
- Zmanjšanje predloge (Boilerplate): ViewSets zmanjšujejo predlogo kode z zagotavljanjem privzetih implementacij za pogoste API operacije. To omogoča razvijalcem, da se osredotočijo na izvajanje prilagojene logike, specifične za njihovo aplikacijo.
- Izboljšana berljivost: ViewSets izboljšujejo berljivost kode z organizacijo povezanih pogledov v en sam razred. To omogoča lažje razumevanje in navigacijo po strukturi API-ja.
- Doslednost: ViewSets pomagajo zagotoviti doslednost v celotnem API-ju z uveljavljanjem standardnega nabora operacij in konvencij. To naredi API bolj predvidljiv in enostavnejši za uporabo.
Osnovna uporaba ViewSets
Začnimo s preprostim primerom uporabe ViewSets za ustvarjanje API-ja za upravljanje izdelkov. Najprej definirajte model:
# models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
def __str__(self):
return self.name
Nato definirajte serializer za Product
model:
# serializers.py
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
Zdaj ustvarite ViewSet za Product
model:
# views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
Na koncu konfigurirajte URL usmerjanje:
# urls.py
from django.urls import path, include
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register(r'products', views.ProductViewSet)
urlpatterns = [
path('', include(router.urls)),
]
Ta konfiguracija bo samodejno ustvarila naslednje API končne točke:
/products/
(GET: list, POST: create)/products/{id}/
(GET: retrieve, PUT: update, PATCH: partial_update, DELETE: destroy)
ModelViewSet
zagotavlja privzete implementacije za vse standardne CRUD operacije. Atribut queryset
določa nabor objektov, na katerih naj deluje ViewSet, atribut serializer_class
pa določa serializer, ki se uporablja za serializacijo in deserializacijo podatkov.
Vrste ViewSets
DRF ponuja več vgrajenih razredov ViewSet, ki ustrezajo različnim primerom uporabe:
ViewSet
: Osnovni razred za vse ViewSets. Zagotavlja osnovno infrastrukturo za obravnavanje zahtevkov in odgovorov.ReadOnlyModelViewSet
: ViewSet, ki zagotavlja samo-bralne operacije (list
inretrieve
). To je uporabno za API-je, ki omogočajo samo pridobivanje podatkov.ModelViewSet
: ViewSet, ki zagotavlja vse standardne CRUD operacije (list
,create
,retrieve
,update
indestroy
). To je najbolj pogosto uporabljen ViewSet za API-je, ki temeljijo na modelih.GenericViewSet
: ViewSet, ki zagotavlja generično implementacijo za pogoste API operacije. To se lahko uporablja kot osnovni razred za ustvarjanje lastnih ViewSets.
Izbira pravega ViewSet je odvisna od specifičnih zahtev vašega API-ja. Če potrebujete samo samo-bralne operacije, uporabite ReadOnlyModelViewSet
. Če potrebujete vse standardne CRUD operacije, uporabite ModelViewSet
. Če potrebujete večji nadzor nad obnašanjem API-ja, lahko ustvarite lasten ViewSet z dedovanjem iz GenericViewSet
ali ViewSet
.
Prilagajanje ViewSets
Medtem ko vgrajeni ViewSets zagotavljajo priročen način za ustvarjanje API-jev, boste morda morali prilagoditi njihovo obnašanje, da izpolnite specifične zahteve. DRF ponuja več načinov za prilagajanje ViewSets, vključno s preglasitvijo metod, dodajanjem lastnih dejanj in uporabo lastnih serializerjev.
Preglasitev Metod
Privzete implementacije standardnih API operacij lahko preglasite tako, da v svojem razredu ViewSet definirate metode z istimi imeni. Na primer, lahko preglasite metodo create
, da dodate lastno logiko pred ali po ustvarjanju novega objekta:
# views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
from rest_framework.response import Response
from rest_framework import status
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
# Dodajte lastno logiko tukaj pred ustvarjanjem objekta
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
V tem primeru metoda create
preglasi privzeto implementacijo in doda lastno logiko pred ustvarjanjem objekta. Metoda perform_create
se pokliče za dejansko ustvarjanje objekta, odgovor pa se vrne s statusno kodo 201 Created
.
Dodajanje Lastnih Dejanj
Z dekoraterjem @action
lahko dodate lastna dejanja svojemu ViewSet. Lastna dejanja vam omogočajo definiranje novih API končnih točk, ki izvajajo specifične operacije na virih, s katerimi upravlja ViewSet. Na primer, lahko dodate dejanje za označitev izdelka kot priljubljenega:
# views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
@action(detail=True, methods=['post'])
def feature(self, request, pk=None):
product = self.get_object()
product.is_featured = True
product.save()
serializer = self.get_serializer(product)
return Response(serializer.data)
V tem primeru dekorater @action
definira novo API končno točko /products/{id}/feature/
, ki označi izdelek kot priljubljenega. Argument detail=True
pomeni, da dejanje deluje na določeni instanci modela. Argument methods=['post']
določa, da dejanje sprejema samo POST zahteve.
Uporaba Lastnih Serializerjev
Z lastnimi serializerji lahko prilagodite način, kako ViewSet serializira in deserializira podatke. To je koristno, ko morate obravnavati kompleksne podatkovne strukture ali izvajati lastno validacijo. Na primer, z lastnim serializerjem lahko vključite povezane podatke v API odgovor:
# serializers.py
from rest_framework import serializers
from .models import Product, Category
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['id', 'name']
class ProductSerializer(serializers.ModelSerializer):
category = CategorySerializer(read_only=True)
class Meta:
model = Product
fields = '__all__'
# views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
V tem primeru ProductSerializer
vključuje CategorySerializer
za serializacijo povezanih podatkov kategorije. To vam omogoča, da pridobite informacije o kategoriji skupaj z informacijami o izdelku v eni API zahtevi.
Napredne Tehnike ViewSet
Poleg osnovne uporabe in prilagajanja ViewSets ponujajo napredne tehnike za gradnjo sofisticiranih API-jev:
Filtriranje
DRF ponuja zmogljive možnosti filtriranja, ki vam omogočajo filtriranje nabora poizvedb na podlagi parametrov zahtevka. Atribut filter_backends
lahko uporabite za določanje uporabljenih filtrirnih zaledij. Na primer, lahko uporabite SearchFilter
, da uporabnikom omogočite iskanje izdelkov po imenu ali opisu:
# views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
from rest_framework import filters
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
filter_backends = [filters.SearchFilter]
search_fields = ['name', 'description']
V tem primeru atribut filter_backends
določa, da naj se uporablja SearchFilter
. Atribut search_fields
določa polja, po katerih naj se išče.
Paginacija
DRF ponuja možnosti paginacije, ki vam omogočajo, da razdelite nabor poizvedb na manjše strani. To je koristno pri obravnavanju velikih naborov podatkov. Atribut pagination_class
lahko uporabite za določanje uporabljenega razreda paginacije. Na primer, lahko uporabite PageNumberPagination
za paginiranje rezultatov z uporabo številk strani:
# views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
from rest_framework.pagination import PageNumberPagination
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
pagination_class = PageNumberPagination
V tem primeru atribut pagination_class
določa, da naj se uporablja PageNumberPagination
. Svoje vedenje paginacije lahko prilagodite tudi z ustvarjanjem lastnega razreda paginacije.
Avtentikacija in Dovoljenja
DRF ponuja prilagodljive mehanizme avtentikacije in dovoljenj, ki vam omogočajo nadzor dostopa do vaših API končnih točk. Atributa authentication_classes
in permission_classes
lahko uporabite za določanje uporabljenih razredov avtentikacije in dovoljenj. Na primer, lahko uporabite TokenAuthentication
za avtentikacijo uporabnikov z uporabo žetonov in IsAuthenticated
dovoljenje za dovoljenje samo avtenticiranim uporabnikom za dostop do API-ja:
# views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
V tem primeru atribut authentication_classes
določa, da naj se uporablja TokenAuthentication
, atribut permission_classes
pa določa, da naj se uporablja IsAuthenticated
dovoljenje.
Najboljše Prakse za Uporabo ViewSets
Da zagotovite, da so vaši ViewSets dobro zasnovani in vzdrževani, sledite tem najboljšim praksam:
- Osredotočite ViewSets: Vsak ViewSet naj bo odgovoren za upravljanje enega vira ali tesno povezanega nabora virov. Izogibajte se ustvarjanju prekompleksnih ViewSets, ki obravnavajo več nepovezanih operacij.
- Uporabite ustrezne vrste ViewSet: Izberite vrsto ViewSet, ki najbolje ustreza zahtevam vašega API-ja. Uporabite
ReadOnlyModelViewSet
za samo-bralne API-je,ModelViewSet
za CRUD API-je, terGenericViewSet
aliViewSet
za lastne API-je. - Sledite RESTful načelom: Zasnovajte svoje API končne točke v skladu z RESTful načeli. Uporabite standardne HTTP metode (GET, POST, PUT, PATCH, DELETE) za izvajanje operacij na virih.
- Uporabite serializerje za validacijo podatkov: Uporabite serializerje za validacijo podatkov, ki se pošiljajo v API in prejemajo iz njega. To pomaga zagotoviti celovitost podatkov in preprečiti napake.
- Izvedite ustrezno avtentikacijo in dovoljenja: Zavarujte svoje API končne točke z izvajanjem ustrezne avtentikacije in dovoljenj. To pomaga zaščititi vaše podatke pred nepooblaščenim dostopom.
- Napišite obsežne teste: Napišite obsežne teste, da zagotovite, da vaši ViewSets delujejo pravilno. To pomaga preprečiti regresije in olajša vzdrževanje kode.
Premisleki o Internacionalizaciji (i18n) in Lokalizaciji (l10n)
Pri gradnji API-jev za globalno občinstvo je bistveno, da razmislite o internacionalizaciji (i18n) in lokalizaciji (l10n). ViewSets je mogoče prilagoditi za podporo več jezikom in regijam:
- Polja Serializerja: Uporabite polja serializerja DRF z ustreznimi prevajalskimi funkcijami (npr.
gettext
iz Django-jevega i18n okvira), da prikažete prevedene oznake polj in pomožna besedila. - Sporočila o Napakah: Zagotovite, da so sporočila o napakah, ki jih vrača API, prevedena v uporabnikov najljubši jezik.
- Oblikovanje Datuma in Časa: Uporabite ustrezno oblikovanje datuma in časa glede na lokalizacijo uporabnika. DRF ponuja možnosti za prilagajanje formatov datuma in časa.
- Oblikovanje Valute: Oblikujte vrednosti valute v skladu z lokalizacijo uporabnika. Razmislite o uporabi knjižnic, kot je
babel
, za oblikovanje valute. Na primer, cena 1234,56 USD se lahko oblikuje kot $1,234.56 v ZDA, vendar kot 1.234,56 $ v nekaterih evropskih državah. - Časovni Pasovi: Pravilno obravnavajte časovne pasove. Shranjujte datume in čase v UTC in jih pretvorite v lokalni časovni pas uporabnika, ko jih prikazujete.
Na primer, izdelek ima lahko opis, ki ga je treba prevesti. V serializerju bi uporabili Django-jev prevajalski sistem:
# serializers.py
from rest_framework import serializers
from django.utils.translation import gettext_lazy as _
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
description = serializers.CharField(help_text=_("Opis izdelka"))
class Meta:
model = Product
fields = '__all__'
In v vaših predlogah ali kodi, ki uporablja ta serializer, zagotovite pravilno aktiviran jezik.
Primer: E-trgovinski API z Mednarodno Podporo
Predstavljajte si e-trgovinski API, ki globalno prodaja izdelke. Product
model bi lahko vključeval polja, kot so name
, description
, price
in image
. API mora podpirati več jezikov in valut.
ViewSet bi obravnaval osnovne CRUD operacije za izdelke. Serializerji bi bili prilagojeni za podporo prevajanja imena in opisa izdelka. API bi vključeval tudi končne točke za pridobivanje izdelkov po kategorijah, filtriranje izdelkov po cenovnem razponu in iskanje izdelkov po ključnih besedah. Te funkcije bi morale upoštevati internacionalizacijo, zlasti glede iskalnih izrazov in opisov izdelkov, ki se lahko razlikujejo med jeziki.
Primer URL-jev:
/en/products/
- Seznam izdelkov v angleščini/fr/products/
- Seznam izdelkov v francoščini/en/products/?currency=USD
- Seznam izdelkov v USD/fr/products/123/?currency=EUR
- Podrobnosti izdelka 123 v francoščini, cena prikazana v EUR
Zaključek
Django REST Framework ViewSets ponujajo zmogljiv in eleganten način organizacije vaših API končnih točk. Z enkapsulacijo povezanih pogledov v en sam razred, ViewSets spodbujajo ponovno uporabo kode, poenostavljajo usmerjanje in izboljšujejo berljivost kode. Zmožnost prilagajanja ViewSets s preglasitvijo metod, dodajanjem lastnih dejanj in uporabo lastnih serializerjev vam omogoča, da jih prilagodite specifičnim zahtevam vašega API-ja. Z upoštevanjem najboljših praks, opisanih v tem vodniku, lahko zagotovite, da so vaši ViewSets dobro zasnovani, vzdrževani in razširljivi, kar vodi do robustnih in učinkovitih API-jev.
Ne pozabite upoštevati internacionalizacije in lokalizacije pri gradnji API-jev za globalno občinstvo. Prilagodite svoje ViewSets in serializerje za podporo več jezikom, valutam in časovnim pasovom, da zagotovite brezhibno izkušnjo uporabnikom po vsem svetu.
Z obvladovanjem ViewSets lahko svoje veščine Django REST Framework dvignete na višjo raven in gradite API-je, ki so hkrati zmogljivi in vzdrževani. To prispeva k visokokakovostni programski opremi in pozitivni uporabniški izkušnji za vaše globalno občinstvo.
Ta vodnik bi moral služiti kot trdna osnova za razumevanje in izvajanje ViewSets v vaših projektih Django REST Framework. Nadaljujte z vadbo, eksperimentiranjem in raziskovanjem dokumentacije DRF, da postanete pravi mojster ViewSets!