Naučte se efektivně organizovat API Django REST Framework pomocí ViewSets. Tato příručka zahrnuje vše od základního použití po pokročilé úpravy.
Django REST Framework ViewSets: Zvládnutí organizace API koncových bodů
V moderním webovém vývoji je budování robustních a dobře strukturovaných API klíčové. Django REST Framework (DRF) je výkonný nástroj pro vytváření RESTful API s Django. Zatímco DRF nabízí různé nástroje pro vytváření koncových bodů API, ViewSets poskytují elegantní způsob, jak uspořádat související pohledy do jedné třídy, což vede k čistšímu a lépe udržovatelnému kódu. Tato obsáhlá příručka podrobně prozkoumá ViewSets, včetně jejich výhod, použití a pokročilých technik přizpůsobení.
Co jsou ViewSets?
ViewSet je View založený na třídě, který poskytuje implementace pro standardní operace, jako jsou list
, create
, retrieve
, update
a destroy
. Namísto definování samostatných pohledů pro každou operaci, ViewSet je kombinuje do jedné třídy, což zjednodušuje strukturu API a snižuje duplikaci kódu. ViewSets jsou zvláště užitečné při práci s API založenými na modelech, kde jsou tyto standardní operace běžně vyžadovány. Představte si ViewSet jako logické seskupení operací na konkrétním zdroji.
Výhody používání ViewSets
- Opakované použití kódu: ViewSets podporují opakované použití kódu zapouzdřením běžné logiky API do jedné třídy. To snižuje redundanci a usnadňuje údržbu kódu.
- Zjednodušené směrování: ViewSets zjednodušují směrování seskupením souvisejících pohledů pod jednu předponu URL. To má za následek čistší a lépe uspořádanou strukturu URL.
- Snížení boilerplate: ViewSets snižují boilerplate kód poskytnutím výchozích implementací pro běžné operace API. To umožňuje vývojářům soustředit se na implementaci vlastní logiky specifické pro jejich aplikaci.
- Zlepšení čitelnosti: ViewSets zlepšují čitelnost kódu uspořádáním souvisejících pohledů do jedné třídy. Díky tomu je struktura API snadněji srozumitelná a navigovatelná.
- Konzistence: ViewSets pomáhají zajistit konzistenci napříč API prosazováním standardní sady operací a konvencí. Díky tomu je API předvídatelnější a snadněji se používá.
Základní použití ViewSets
Začněme jednoduchým příkladem použití ViewSets k vytvoření API pro správu produktů. Nejprve definujte 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
Dále definujte serializátor pro model Product
:
# serializers.py
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
Nyní vytvořte ViewSet pro model Product
:
# 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
Nakonec nakonfigurujte směrování URL:
# 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)),
]
Tato konfigurace automaticky vygeneruje následující koncové body API:
/products/
(GET: list, POST: create)/products/{id}/
(GET: retrieve, PUT: update, PATCH: partial_update, DELETE: destroy)
ModelViewSet
poskytuje výchozí implementace pro všechny standardní operace CRUD. Atribut queryset
určuje sadu objektů, se kterými má ViewSet pracovat, a atribut serializer_class
určuje serializátor, který se má použít pro serializaci a deserializaci dat.
Typy ViewSets
DRF poskytuje několik vestavěných tříd ViewSet, které vyhovují různým případům použití:
ViewSet
: Základní třída pro všechny ViewSets. Poskytuje základní infrastrukturu pro zpracování požadavků a odpovědí.ReadOnlyModelViewSet
: ViewSet, který poskytuje operace pouze pro čtení (list
aretrieve
). To je užitečné pro API, která umožňují pouze načítání dat.ModelViewSet
: ViewSet, který poskytuje všechny standardní operace CRUD (list
,create
,retrieve
,update
adestroy
). Toto je nejčastěji používaný ViewSet pro API založené na modelech.GenericViewSet
: ViewSet, který poskytuje obecnou implementaci pro běžné operace API. To lze použít jako základní třídu pro vytváření vlastních ViewSets.
Výběr správného ViewSet závisí na konkrétních požadavcích vašeho API. Pokud potřebujete pouze operace pro čtení, použijte ReadOnlyModelViewSet
. Pokud potřebujete všechny standardní operace CRUD, použijte ModelViewSet
. Pokud potřebujete větší kontrolu nad chováním API, můžete vytvořit vlastní ViewSet děděním z GenericViewSet
nebo ViewSet
.
Přizpůsobení ViewSets
Zatímco vestavěné ViewSets poskytují pohodlný způsob vytváření API, možná budete muset přizpůsobit jejich chování tak, aby splňovalo specifické požadavky. DRF poskytuje několik způsobů, jak přizpůsobit ViewSets, včetně přepsání metod, přidání vlastních akcí a použití vlastních serializátorů.
Přepsání metod
Můžete přepsat výchozí implementace standardních operací API definováním metod se stejnými názvy ve vaší třídě ViewSet. Můžete například přepsat metodu create
a přidat vlastní logiku před nebo po vytvoření nového objektu:
# 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)
# Add custom logic here before creating the object
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
V tomto příkladu metoda create
přepíše výchozí implementaci a přidá vlastní logiku před vytvořením objektu. Metoda perform_create
se volá pro skutečné vytvoření objektu a odpověď se vrátí se stavovým kódem 201 Created
.
Přidání vlastních akcí
Do svého ViewSet můžete přidat vlastní akce pomocí dekorátoru @action
. Vlastní akce vám umožňují definovat nové koncové body API, které provádějí specifické operace se zdroji spravovanými ViewSet. Můžete například přidat akci pro označení produktu jako doporučeného:
# 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 tomto příkladu dekorátor @action
definuje nový koncový bod API /products/{id}/feature/
, který označí produkt jako doporučený. Argument detail=True
označuje, že akce operuje na konkrétní instanci modelu. Argument methods=['post']
určuje, že akce přijímá pouze požadavky POST.
Použití vlastních serializátorů
Můžete použít vlastní serializátory k přizpůsobení způsobu, jakým jsou data serializována a deserializována ViewSet. To je užitečné, když potřebujete zpracovávat složité datové struktury nebo provádět vlastní ověření. Můžete například použít vlastní serializátor k zahrnutí souvisejících dat do odpovědi API:
# 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 tomto příkladu ProductSerializer
zahrnuje CategorySerializer
pro serializaci souvisejících dat kategorie. To vám umožní načíst informace o kategorii spolu s informacemi o produktu v jednom požadavku API.
Pokročilé techniky ViewSet
Kromě základního použití a přizpůsobení nabízejí ViewSets pokročilé techniky pro vytváření sofistikovaných API:
Filtrování
DRF poskytuje výkonné možnosti filtrování, které vám umožňují filtrovat queryset na základě parametrů požadavku. Můžete použít atribut filter_backends
k určení filtrovacích backendů, které se mají použít. Můžete například použít SearchFilter
, aby uživatelé mohli vyhledávat produkty podle názvu nebo popisu:
# 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 tomto příkladu atribut filter_backends
určuje, že by se měl použít SearchFilter
. Atribut search_fields
určuje pole, která by se měla prohledávat.
Stránkování
DRF poskytuje možnosti stránkování, které vám umožňují rozdělit queryset na menší stránky. To je užitečné při práci s velkými datovými sadami. Můžete použít atribut pagination_class
k určení třídy stránkování, která se má použít. Můžete například použít PageNumberPagination
ke stránkování výsledků pomocí čísel stránek:
# 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 tomto příkladu atribut pagination_class
určuje, že by se měla použít PageNumberPagination
. Můžete také přizpůsobit chování stránkování vytvořením vlastní třídy stránkování.
Autentizace a oprávnění
DRF poskytuje flexibilní mechanismy autentizace a oprávnění, které vám umožňují řídit přístup ke koncovým bodům API. Můžete použít atributy authentication_classes
a permission_classes
k určení tříd autentizace a oprávnění, které se mají použít. Můžete například použít TokenAuthentication
k autentizaci uživatelů pomocí tokenů a oprávnění IsAuthenticated
, aby k API měli přístup pouze autentizovaní uživatelé:
# 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 tomto příkladu atribut authentication_classes
určuje, že by se měla použít TokenAuthentication
, a atribut permission_classes
určuje, že by se mělo použít oprávnění IsAuthenticated
.
Osvědčené postupy pro používání ViewSets
Abyste zajistili, že vaše ViewSets budou dobře navržené a udržovatelné, dodržujte tyto osvědčené postupy:
- Udržujte ViewSets zaměřené: Každý ViewSet by měl být zodpovědný za správu jediného zdroje nebo úzce související sady zdrojů. Vyhněte se vytváření příliš složitých ViewSets, které zpracovávají více nesouvisejících operací.
- Používejte vhodné typy ViewSet: Vyberte typ ViewSet, který nejlépe vyhovuje požadavkům vašeho API. Použijte
ReadOnlyModelViewSet
pro API pouze pro čtení,ModelViewSet
pro API CRUD aGenericViewSet
neboViewSet
pro vlastní API. - Dodržujte principy RESTful: Navrhněte koncové body API podle principů RESTful. Používejte standardní metody HTTP (GET, POST, PUT, PATCH, DELETE) k provádění operací se zdroji.
- Používejte serializátory pro ověření dat: Používejte serializátory k ověření dat, která jsou odesílána do API a přijímána z API. To pomáhá zajistit integritu dat a předcházet chybám.
- Implementujte správnou autentizaci a oprávnění: Zabezpečte své koncové body API implementací správné autentizace a oprávnění. To pomáhá chránit vaše data před neoprávněným přístupem.
- Pište komplexní testy: Pište komplexní testy, abyste zajistili, že vaše ViewSets fungují správně. To pomáhá předcházet regresím a usnadňuje údržbu kódu.
Mezinárodnost (i18n) a lokalizace (l10n)
Při vytváření API pro globální publikum je nezbytné zvážit mezinárodnost (i18n) a lokalizaci (l10n). ViewSets lze upravit tak, aby podporovaly více jazyků a regionů:
- Pole serializátoru: Používejte pole serializátoru DRF s příslušnými překladatelskými funkcemi (např.
gettext
z rámce i18n Django) k zobrazení přeložených popisků polí a textů nápovědy. - Chybové zprávy: Zajistěte, aby chybové zprávy vracené API byly přeloženy do preferovaného jazyka uživatele.
- Formátování data a času: Používejte příslušné formátování data a času na základě národního prostředí uživatele. DRF poskytuje možnosti pro přizpůsobení formátů data a času.
- Formátování měny: Formátujte hodnoty měny podle národního prostředí uživatele. Zvažte použití knihoven jako
babel
pro formátování měny. Například cena 1234,56 USD může být formátována jako 1 234,56 USD v USA, ale jako 1 234,56 $ v některých evropských zemích. - Časová pásma: Správně zpracovávejte časová pásma. Ukládejte data a časy ve formátu UTC a při jejich zobrazování je převeďte na místní časové pásmo uživatele.
Produkt může mít například popis, který je třeba přeložit. V rámci serializátoru byste použili překladatelský systém Django:
# 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=_("Popis produktu"))
class Meta:
model = Product
fields = '__all__'
A ve svých šablonách nebo kódu, který používá tento serializátor, zajistěte aktivaci správného jazyka.
Příklad: API elektronického obchodu s mezinárodní podporou
Představte si API elektronického obchodu prodávajícího produkty globálně. Model Product
může obsahovat pole jako name
, description
, price
a image
. API musí podporovat více jazyků a měn.
ViewSet by zpracovával základní operace CRUD pro produkty. Serializátory by byly upraveny tak, aby podporovaly překlad názvu a popisu produktu. API by také zahrnovalo koncové body pro načítání produktů podle kategorie, filtrování produktů podle cenového rozpětí a vyhledávání produktů podle klíčového slova. Tyto funkce by musely zohledňovat internacionalizaci, zejména kolem vyhledávacích dotazů a popisů produktů, které se mohou mezi jazyky lišit.
Příklady URL:
/en/products/
- Seznam produktů v angličtině/fr/products/
- Seznam produktů ve francouzštině/en/products/?currency=USD
- Seznam produktů v USD/fr/products/123/?currency=EUR
- Podrobnosti o produktu 123 ve francouzštině, cena zobrazena v EUR
Závěr
Django REST Framework ViewSets poskytují výkonný a elegantní způsob, jak uspořádat koncové body API. Zapouzdřením souvisejících pohledů do jedné třídy ViewSets podporují opakované použití kódu, zjednodušují směrování a zlepšují čitelnost kódu. Díky možnosti přizpůsobit ViewSets pomocí přepsání metod, přidání vlastních akcí a použití vlastních serializátorů je můžete přizpůsobit tak, aby splňovaly specifické požadavky vašeho API. Dodržováním osvědčených postupů uvedených v této příručce můžete zajistit, že vaše ViewSets budou dobře navržené, udržovatelné a škálovatelné, což povede k robustním a efektivním API.
Nezapomeňte zvážit internacionalizaci a lokalizaci při vytváření API pro globální publikum. Upravte své ViewSets a serializátory tak, aby podporovaly více jazyků, měn a časových pásem, a poskytly tak bezproblémový zážitek uživatelům po celém světě.
Zvládnutím ViewSets můžete posunout své dovednosti Django REST Framework na další úroveň a vytvářet API, která jsou výkonná i udržovatelná. To přispívá k vysoce kvalitnímu softwaru a pozitivní uživatelské zkušenosti pro vaše globální publikum.
Tato příručka by měla sloužit jako pevný základ pro pochopení a implementaci ViewSets ve vašich projektech Django REST Framework. Pokračujte v procvičování, experimentování a prozkoumávání dokumentace DRF, abyste se stali skutečným mistrem ViewSet!