- Введение
- Базовое использование
- Продвинутые запросы
- Работа с файлами
- Массовые операции
- Лучшие практики
- Продвинутые техники
Данная документация описывает работу с Django views, включая классы-представления (Class-Based Views) и функции-представления (Function-Based Views). В документации представлены примеры базового и продвинутого использования, работа с файлами и рекомендуемые практики.
from django.shortcuts import render
from django.http import HttpRequest
def products_list(request: HttpRequest):
context = {
"products": Product.objects.all(),
}
return render(request, 'products-list.html', context=context)
from django.views.generic import ListView
class ProductListView(ListView):
template_name = 'products-list.html'
context_object_name = 'products'
queryset = Product.objects.filter(archived=False)
# Использование select_related для связей ForeignKey
class OrderListView(ListView):
queryset = (
Order.objects
.select_related('user') # для ForeignKey
.prefetch_related("products") # для ManyToMany
.filter(status='active')
)
# Сложные фильтры
class AdvancedProductListView(ListView):
def get_queryset(self):
return (
Product.objects
.filter(archived=False)
.exclude(price__lt=100)
.annotate(
total_orders=Count('order'),
revenue=Sum(F('price') * F('order__quantity'))
)
.order_by('-revenue')
)
class ProductManager(models.Manager):
def active(self):
return self.filter(archived=False)
def with_sales_stats(self):
return self.annotate(
total_sales=Count('order'),
revenue=Sum(F('price') * F('order__quantity'))
)
class Product(models.Model):
objects = ProductManager()
from django.core.files.storage import default_storage
class ProductImageUploadView(UpdateView):
model = Product
fields = ['name', 'image']
def form_valid(self, form):
if 'image' in self.request.FILES:
file = self.request.FILES['image']
path = default_storage.save(
f'products/{file.name}',
file
)
self.object.image_path = path
return super().form_valid(form)
from django.core.files.uploadhandler import TemporaryFileUploadHandler
class LargeFileUploadView(View):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.upload_handlers = [TemporaryFileUploadHandler()]
def post(self, request):
chunk_size = 2500
for chunk in request.FILES['file'].chunks(chunk_size):
# Обработка чанка
process_chunk(chunk)
def bulk_create_products(products_data):
products = [
Product(
name=data['name'],
price=data['price'],
description=data['description']
)
for data in products_data
]
return Product.objects.bulk_create(
products,
batch_size=100,
ignore_conflicts=True
)
def bulk_update_prices(products, price_increase):
for product in products:
product.price += price_increase
Product.objects.bulk_update(
products,
['price'],
batch_size=100
)
from typing import List, Optional
from django.db.models import QuerySet
class ProductService:
def get_active_products(self) -> QuerySet[Product]:
return Product.objects.filter(archived=False)
def create_product(self, data: dict) -> Product:
return Product.objects.create(**data)
class OptimizedListView(ListView):
def get_queryset(self):
queryset = super().get_queryset()
return queryset.only('name', 'price') # Выбираем только нужные поля
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['cached_categories'] = cache.get_or_set(
'categories',
lambda: list(Category.objects.all()),
timeout=3600
)
return context
import time
from django.db import connection
class QueryCountMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start_time = time.time()
initial_queries = len(connection.queries)
response = self.get_response(request)
total_time = time.time() - start_time
total_queries = len(connection.queries) - initial_queries
print(f'Queries: {total_queries}, Time: {total_time:.2f}s')
return response
class SerializerMixin:
serializer_class = None
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def get_serialized_data(self):
return self.get_serializer(self.get_queryset(), many=True).data
class ProductAPIView(SerializerMixin, ListView):
serializer_class = ProductSerializer
queryset = Product.objects.all()
def get(self, request, *args, **kwargs):
data = self.get_serialized_data()
return JsonResponse(data, safe=False)
class DynamicFilterMixin:
def get_queryset(self):
queryset = super().get_queryset()
filter_params = {
key: value
for key, value in self.request.GET.items()
if key in self.filterable_fields
}
return queryset.filter(**filter_params)
class ProductListView(DynamicFilterMixin, ListView):
model = Product
filterable_fields = ['category', 'price', 'archived']