Django REST Framework API-laringizni ViewSet-lar yordamida samarali tashkil qilishni o'rganing. Ushbu qo'llanma asosiy foydalanishdan tortib to ilg'or sozlashgacha bo'lgan hamma narsani qamrab oladi, amaliy misollar va eng yaxshi amaliyotlarni taqdim etadi.
Django REST Framework ViewSets: Mastering API Endpoint Organization
Zamonaviy veb-ishlab chiqishda mustahkam va yaxshi tuzilgan API-larni yaratish juda muhimdir. Django REST Framework (DRF) Django bilan RESTful API-larni yaratish uchun kuchli vositadir. DRF API endpointlarni yaratish uchun turli xil vositalarni taklif qilsa-da, ViewSet-lar tegishli ko'rinishlarni bitta sinfga tashkil qilishning oqlangan usulini ta'minlaydi, bu esa toza va ko'proq saqlanadigan kodga olib keladi. Ushbu keng qamrovli qo'llanma ViewSet-larni batafsil o'rganadi, ularning afzalliklari, foydalanish usullari va ilg'or sozlash usullarini qamrab oladi.
What are ViewSets?
ViewSet - bu standart operatsiyalar, masalan, list
, create
, retrieve
, update
va destroy
uchun ilovalarni taqdim etadigan sinfga asoslangan View. Har bir operatsiya uchun alohida ko'rinishlarni belgilash o'rniga, ViewSet ularni bitta sinfga birlashtiradi, API tuzilishini soddalashtiradi va kodni takrorlashni kamaytiradi. ViewSet-lar, ayniqsa, modelga asoslangan API-lar bilan ishlashda foydalidir, bunda ushbu standart operatsiyalar odatda talab qilinadi. ViewSet-ni ma'lum bir resursdagi operatsiyalarning mantiqiy guruhi sifatida o'ylang.
Benefits of Using ViewSets
- Code Reusability: ViewSet-lar umumiy API mantiqini bitta sinfga birlashtirib, kodni qayta ishlatishga yordam beradi. Bu ortiqchalikni kamaytiradi va kodni saqlashni osonlashtiradi.
- Simplified Routing: ViewSet-lar tegishli ko'rinishlarni bitta URL prefiksi ostida guruhlash orqali marshrutlashni soddalashtiradi. Bu toza va yaxshi tashkil etilgan URL tuzilishiga olib keladi.
- Reduced Boilerplate: ViewSet-lar umumiy API operatsiyalari uchun sukut bo'yicha ilovalarni taqdim etish orqali boilerplate kodini kamaytiradi. Bu ishlab chiquvchilarga o'z ilovalariga xos bo'lgan maxsus mantiqni amalga oshirishga e'tibor qaratishga imkon beradi.
- Improved Readability: ViewSet-lar tegishli ko'rinishlarni bitta sinfga tashkil qilish orqali kodning o'qilishini yaxshilaydi. Bu API tuzilishini tushunish va navigatsiya qilishni osonlashtiradi.
- Consistency: ViewSet-lar standart operatsiyalar va konventsiyalar to'plamini amalga oshirish orqali API bo'ylab izchillikni ta'minlashga yordam beradi. Bu API-ni bashorat qilish osonroq va foydalanish osonroq qiladi.
Basic Usage of ViewSets
Mahsulotlarni boshqarish uchun API yaratish uchun ViewSet-lardan foydalanishning oddiy misoli bilan boshlaylik. Birinchidan, modelni belgilang:
# 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
Keyin, Product
modeli uchun serializerni belgilang:
# serializers.py
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
Endi Product
modeli uchun ViewSet yarating:
# 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
Nihoyat, URL marshrutlashini sozlang:
# 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)),
]
Ushbu konfiguratsiya avtomatik ravishda quyidagi API endpointlarini yaratadi:
/products/
(GET: list, POST: create)/products/{id}/
(GET: retrieve, PUT: update, PATCH: partial_update, DELETE: destroy)
ModelViewSet
barcha standart CRUD operatsiyalari uchun sukut bo'yicha ilovalarni taqdim etadi. queryset
atributi ViewSet operatsiya qilishi kerak bo'lgan ob'ektlar to'plamini belgilaydi va serializer_class
atributi ma'lumotlarni serializatsiya qilish va deserializatsiya qilish uchun ishlatiladigan serializerni belgilaydi.
Types of ViewSets
DRF turli xil foydalanish holatlariga mos keladigan bir nechta o'rnatilgan ViewSet sinflarini taqdim etadi:
ViewSet
: Barcha ViewSet-lar uchun asosiy sinf. U so'rovlar va javoblarni qayta ishlash uchun asosiy infratuzilmani ta'minlaydi.ReadOnlyModelViewSet
: Faqat o'qish uchun operatsiyalarni taqdim etadigan ViewSet (list
varetrieve
). Bu faqat ma'lumotlarni olishga ruxsat beradigan API-lar uchun foydalidir.ModelViewSet
: Barcha standart CRUD operatsiyalarini taqdim etadigan ViewSet (list
,create
,retrieve
,update
vadestroy
). Bu modelga asoslangan API-lar uchun eng ko'p ishlatiladigan ViewSet.GenericViewSet
: Umumiy API operatsiyalari uchun umumiy ilovani taqdim etadigan ViewSet. Bu maxsus ViewSet-larni yaratish uchun asosiy sinf sifatida ishlatilishi mumkin.
To'g'ri ViewSet-ni tanlash sizning API-ning o'ziga xos talablariga bog'liq. Agar sizga faqat o'qish uchun operatsiyalar kerak bo'lsa, ReadOnlyModelViewSet
-dan foydalaning. Agar sizga barcha standart CRUD operatsiyalari kerak bo'lsa, ModelViewSet
-dan foydalaning. Agar sizga API xatti-harakatlarini ko'proq nazorat qilish kerak bo'lsa, GenericViewSet
yoki ViewSet
-dan meros qilib maxsus ViewSet yaratishingiz mumkin.
Customizing ViewSets
O'rnatilgan ViewSet-lar API-larni yaratishning qulay usulini taqdim etsa-da, o'ziga xos talablarga javob berish uchun ularning xatti-harakatlarini sozlash kerak bo'lishi mumkin. DRF ViewSet-larni sozlashning bir nechta usullarini taqdim etadi, jumladan usullarni bekor qilish, maxsus harakatlar qo'shish va maxsus serializerlardan foydalanish.
Overriding Methods
ViewSet sinfida bir xil nomdagi usullarni belgilash orqali standart API operatsiyalarining sukut bo'yicha ilovalarini bekor qilishingiz mumkin. Misol uchun, yangi ob'ektni yaratishdan oldin yoki keyin maxsus mantiqni qo'shish uchun create
usulini bekor qilishingiz mumkin:
# 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)
Ushbu misolda create
usuli sukut bo'yicha ilovani bekor qiladi va ob'ektni yaratishdan oldin maxsus mantiqni qo'shadi. perform_create
usuli ob'ektni aslida yaratish uchun chaqiriladi va javob 201 Created
holat kodi bilan qaytariladi.
Adding Custom Actions
@action
dekoratoridan foydalanib, ViewSet-ga maxsus harakatlar qo'shishingiz mumkin. Maxsus harakatlar ViewSet tomonidan boshqariladigan resurslarda ma'lum operatsiyalarni bajaradigan yangi API endpointlarini belgilashga imkon beradi. Misol uchun, mahsulotni tavsiya etilgan deb belgilash uchun harakat qo'shishingiz mumkin:
# 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)
Ushbu misolda @action
dekoratori mahsulotni tavsiya etilgan deb belgilaydigan yangi API endpointini /products/{id}/feature/
belgilaydi. detail=True
argumenti harakat modelning o'ziga xos misolida ishlashini ko'rsatadi. methods=['post']
argumenti harakat faqat POST so'rovlarini qabul qilishini belgilaydi.
Using Custom Serializers
ViewSet tomonidan ma'lumotlar serializatsiya va deserializatsiya qilinishini sozlash uchun maxsus serializerlardan foydalanishingiz mumkin. Bu murakkab ma'lumotlar tuzilmalarini qayta ishlash yoki maxsus validatsiyani amalga oshirish zarur bo'lganda foydalidir. Misol uchun, API javobida tegishli ma'lumotlarni kiritish uchun maxsus serializerdan foydalanishingiz mumkin:
# 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
Ushbu misolda ProductSerializer
tegishli kategoriya ma'lumotlarini serializatsiya qilish uchun CategorySerializer
-ni o'z ichiga oladi. Bu mahsulot ma'lumotlari bilan birga kategoriya ma'lumotlarini bitta API so'rovida olishga imkon beradi.
Advanced ViewSet Techniques
Asosiy foydalanish va sozlashdan tashqari, ViewSet-lar murakkab API-larni yaratish uchun ilg'or usullarni taklif etadi:
Filtering
DRF so'rov parametrlariga asoslangan holda queryset-ni filtrlashga imkon beradigan kuchli filtrlash imkoniyatlarini taqdim etadi. Qaysi filtrlash backendlardan foydalanishni belgilash uchun filter_backends
atributidan foydalanishingiz mumkin. Misol uchun, foydalanuvchilarga mahsulotlarni nomi yoki tavsifi bo'yicha qidirishga ruxsat berish uchun SearchFilter
-dan foydalanishingiz mumkin:
# 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']
Ushbu misolda filter_backends
atributi SearchFilter
ishlatilishi kerakligini belgilaydi. search_fields
atributi qidirilishi kerak bo'lgan maydonlarni belgilaydi.
Pagination
DRF queryset-ni kichikroq sahifalarga bo'lishga imkon beradigan pagination imkoniyatlarini taqdim etadi. Bu katta ma'lumotlar to'plamlari bilan ishlashda foydalidir. Qaysi pagination sinfidan foydalanishni belgilash uchun pagination_class
atributidan foydalanishingiz mumkin. Misol uchun, sahifa raqamlari yordamida natijalarni sahifalash uchun PageNumberPagination
-dan foydalanishingiz mumkin:
# 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
Ushbu misolda pagination_class
atributi PageNumberPagination
ishlatilishi kerakligini belgilaydi. Shuningdek, o'zingizning pagination sinfingizni yaratib, pagination xatti-harakatlarini sozlashingiz mumkin.
Authentication and Permissions
DRF API endpointlaringizga kirishni nazorat qilishga imkon beradigan moslashuvchan autentifikatsiya va ruxsat mexanizmlarini taqdim etadi. Qaysi autentifikatsiya va ruxsat sinflaridan foydalanishni belgilash uchun authentication_classes
va permission_classes
atributlaridan foydalanishingiz mumkin. Misol uchun, tokenlar yordamida foydalanuvchilarni autentifikatsiya qilish uchun TokenAuthentication
-dan va faqat autentifikatsiya qilingan foydalanuvchilarga API-ga kirishga ruxsat berish uchun IsAuthenticated
ruxsatidan foydalanishingiz mumkin:
# 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]
Ushbu misolda authentication_classes
atributi TokenAuthentication
ishlatilishi kerakligini belgilaydi va permission_classes
atributi IsAuthenticated
ruxsati ishlatilishi kerakligini belgilaydi.
Best Practices for Using ViewSets
ViewSet-laringiz yaxshi ishlab chiqilgan va saqlanadigan bo'lishini ta'minlash uchun quyidagi eng yaxshi amaliyotlarga amal qiling:
- Keep ViewSets focused: Har bir ViewSet bitta resursni yoki unga yaqin bo'lgan resurslar to'plamini boshqarish uchun mas'ul bo'lishi kerak. Bir nechta aloqasi bo'lmagan operatsiyalarni boshqaradigan haddan tashqari murakkab ViewSet-larni yaratishdan saqlaning.
- Use appropriate ViewSet types: API-ning talablariga eng mos keladigan ViewSet turini tanlang. O'qish uchun mo'ljallangan API-lar uchun
ReadOnlyModelViewSet
-dan, CRUD API-lar uchunModelViewSet
-dan va maxsus API-lar uchunGenericViewSet
yokiViewSet
-dan foydalaning. - Follow RESTful principles: API endpointlaringizni RESTful tamoyillarga muvofiq loyihalashtiring. Resurslarda operatsiyalarni bajarish uchun standart HTTP usullaridan (GET, POST, PUT, PATCH, DELETE) foydalaning.
- Use serializers for data validation: API-ga yuborilgan va undan qabul qilingan ma'lumotlarni tekshirish uchun serializerlardan foydalaning. Bu ma'lumotlarning yaxlitligini ta'minlashga va xatolarning oldini olishga yordam beradi.
- Implement proper authentication and permissions: To'g'ri autentifikatsiya va ruxsatlarni amalga oshirish orqali API endpointlaringizni himoya qiling. Bu ma'lumotlaringizni ruxsatsiz kirishdan himoya qilishga yordam beradi.
- Write comprehensive tests: ViewSet-laringiz to'g'ri ishlayotganligini ta'minlash uchun keng qamrovli testlar yozing. Bu regressiyalarning oldini olishga yordam beradi va kodni saqlashni osonlashtiradi.
Internationalization (i18n) and Localization (l10n) Considerations
When building APIs for a global audience, it's essential to consider internationalization (i18n) and localization (l10n). ViewSets can be adapted to support multiple languages and regions:
- Serializer Fields: Use DRF's serializer fields with appropriate translation functions (e.g.,
gettext
from Django's i18n framework) to display translated field labels and help texts. - Error Messages: Ensure that error messages returned by the API are translated into the user's preferred language.
- Date and Time Formatting: Use appropriate date and time formatting based on the user's locale. DRF provides options for customizing date and time formats.
- Currency Formatting: Format currency values according to the user's locale. Consider using libraries like
babel
for currency formatting. For instance, a price of 1234.56 in USD might be formatted as $1,234.56 in the US, but as 1.234,56 $ in some European countries. - Time Zones: Handle time zones correctly. Store dates and times in UTC and convert them to the user's local time zone when displaying them.
For instance, a product might have a description that needs to be translated. You would use Django's translation system within the serializer:
# 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=_("Product description"))
class Meta:
model = Product
fields = '__all__'
And in your templates or code that uses this serializer, ensure the proper language is activated.
Example: E-commerce API with International Support
Imagine an e-commerce API selling products globally. The Product
model might include fields like name
, description
, price
, and image
. The API needs to support multiple languages and currencies.
The ViewSet would handle the basic CRUD operations for products. The serializers would be customized to support translation of the product name and description. The API would also include endpoints for retrieving products by category, filtering products by price range, and searching for products by keyword. These features would need to consider internationalization, particularly around search terms and product descriptions that may vary between languages.
Example URLS:
/en/products/
- List of products in English/fr/products/
- List of products in French/en/products/?currency=USD
- List of products in USD/fr/products/123/?currency=EUR
- Details of product 123 in French, price displayed in EUR
Conclusion
Django REST Framework ViewSet-lar API endpointlaringizni tashkil qilishning kuchli va oqlangan usulini taqdim etadi. Tegishli ko'rinishlarni bitta sinfga birlashtirib, ViewSet-lar kodni qayta ishlatishni rag'batlantiradi, marshrutlashni soddalashtiradi va kodning o'qilishini yaxshilaydi. Usullarni bekor qilish, maxsus harakatlar qo'shish va maxsus serializerlardan foydalanish orqali ViewSet-larni sozlash qobiliyati bilan siz ularni API-ning o'ziga xos talablariga moslashtirishingiz mumkin. Ushbu qo'llanmada keltirilgan eng yaxshi amaliyotlarga amal qilib, ViewSet-laringiz yaxshi ishlab chiqilgan, saqlanadigan va kengaytiriladigan bo'lishini ta'minlashingiz mumkin, bu esa mustahkam va samarali API-larga olib keladi.
Global auditoriya uchun API-larni yaratishda xalqarolashtirish va mahalliylashtirishni hisobga olishni unutmang. ViewSet-lar va serializerlaringizni bir nechta tillarni, valyutalarni va vaqt zonalarini qo'llab-quvvatlash uchun moslashtiring, shunda butun dunyo bo'ylab foydalanuvchilar uchun uzluksiz tajriba ta'minlanadi.
ViewSet-larni o'zlashtirib, siz Django REST Framework ko'nikmalaringizni keyingi bosqichga olib chiqishingiz va kuchli va saqlanadigan API-larni yaratishingiz mumkin. Bu yuqori sifatli dasturiy ta'minotga va global auditoriyangiz uchun ijobiy foydalanuvchi tajribasiga hissa qo'shadi.
Ushbu qo'llanma Django REST Framework loyihalarida ViewSet-larni tushunish va amalga oshirish uchun mustahkam asos bo'lib xizmat qilishi kerak. Haqiqiy ViewSet ustasi bo'lish uchun mashq qilishni, tajriba o'tkazishni va DRF hujjatlarini o'rganishni davom eting!