Разработка веб-приложений с использованием фреймворка Django и языка Python
Основы создания веб-сайта на Django
Рассмотрим стандартный процесс разработки полноценного сайта на Django. Первый шаг - установка фреймворка через pip:
pip install djangoсоздание сайтов python django (создание веб-сайтов на django с использованием python)
Далее создается проект и приложение:
django-admin startproject mysite
cd mysite
python manage.py startapp blogPython web django (web-фреймворк django)
Регистрируем приложение в mysite/settings.py в INSTALLED_APPS.
Создаем модель для поста в blog/models.py:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
pub_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.titlePython web flask (web-фреймворк flask)
Выполняем миграции:
python manage.py makemigrations
python manage.py migratePython web server (web-сервер на python)
Регистрируем модель в админке (blog/admin.py):
from django.contrib import admin
from .models import Post
admin.site.register(Post)Python 3 веб приложение (веб-приложение на python 3)
Создаем суперпользователя для доступа в админку:
python manage.py createsuperuserPython веб сервисы (веб-сервисы на python)
Теперь представление для списка постов в blog/views.py:
from django.shortcuts import render
from .models import Post
def post_list(request):
posts = Post.objects.all().order_by('-pub_date')
return render(request, 'blog/post_list.html', {'posts': posts})примеры python веб (примеры веб-разработки на python)
Создаем шаблон blog/templates/blog/post_list.html:
<!DOCTYPE html>
<html>
<head><title>Мой блог</title></head>
<body>
<h2>Список постов</h2>
<ul>
{% for post in posts %}
<li><a href="{% url 'post_detail' post.id %}">{{ post.title }}</a> ({{ post.pub_date }})</li>
{% empty %}
<li>Нет постов.</li>
{% endfor %}
</ul>
</body>
</html>создание сайта на python (создание сайта на python)
Добавляем маршрут в blog/urls.py (не забудьте создать файл):
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
]Django python создание приложения (создание веб-приложения на django)
Подключаем URL-файл приложения в главном mysite/urls.py:
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
]библиотека django python (библиотека django для веб-разработки на python)
Запускаем сервер:
python manage.py runserverPython django практика (практика django на python)
Открываем http://127.0.0.1:8000/blog/.
Как использовать Class-Based Views вместо функций для сокращения кода?
Django предоставляет встроенные обобщенные представления. Например, для списка постов можно написать:
from django.views.generic import ListView
from .models import Post
class PostListView(ListView):
model = Post
template_name = 'blog/post_list.html'
context_object_name = 'posts'
ordering = ['-pub_date']
В blog/urls.py указываем path('', PostListView.as_view(), name='post_list'). Шаблон остается без изменений.
Типичная ошибка: неверно указан context_object_name. По умолчанию объектный список именуется object_list, что приводит к отсутствию переменной posts в шаблоне. Решение: либо переименовать шаблонные переменные, либо задать context_object_name.
Как добавить REST API с помощью Django REST Framework?
Установите пакет:
pip install djangorestframework
Добавьте 'rest_framework' в INSTALLED_APPS. Создайте сериализатор (blog/serializers.py):
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['id', 'title', 'content', 'pub_date']
Представление-набор:
from rest_framework import viewsets
from .models import Post
from .serializers import PostSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
Подключите маршруты через Router:
from rest_framework.routers import DefaultRouter
from django.urls import include, path
from .views import PostViewSet
router = DefaultRouter()
router.register(r'posts', PostViewSet)
urlpatterns = [
path('api/', include(router.urls)),
]
Теперь API доступно по адресу /api/posts/.
Проблема: забыли установить djangorestframework в виртуальное окружение. Решение: проверить список установленных пакетов через pip list.
Как подключить Bootstrap для быстрой стилизации?
Используйте HTML-шаблон с Bootstrap CDN. Например, в base.html:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<title>{% block title %}Мой сайт{% endblock %}</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="{% url 'post_list' %}">Блог</a>
</div>
</nav>
<div class="container mt-4">
{% block content %}{% endblock %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
Шаблоны наследуют base.html. Пример post_list.html:
{% extends 'base.html' %}
{% block content %}
<h2>Список постов</h2>
<div class="list-group">
{% for post in posts %}
<a href="{% url 'post_detail' post.id %}" class="list-group-item list-group-item-action">
<h5 class="mb-1">{{ post.title }}</h5>
<small>{{ post.pub_date }}</small>
</a>
{% empty %}
<p class="text-muted">Нет постов.</p>
{% endfor %}
</div>
{% endblock %}
Как добавить регистрацию и вход пользователей?
Django имеет встроенную систему аутентификации. Создайте приложение accounts с представлениями:
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.views.generic import CreateView
class RegisterView(CreateView):
form_class = UserCreationForm
template_name = 'registration/register.html'
success_url = reverse_lazy('login')
def form_valid(self, form):
user = form.save()
login(self.request, user)
return redirect('home')
Включите стандартные URL-ы аутентификации:
from django.contrib.auth import views as auth_views
urlpatterns = [
path('login/', auth_views.LoginView.as_view(), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
path('register/', RegisterView.as_view(), name='register'),
]
Не забудьте создать шаблоны для логина и регистрации.
Типичная ошибка: отсутствует шаблон registration/login.html или registration/register.html. Решение: создать соответствующие файлы с формой.
Использование сигналов и промежуточного ПО
Как автоматически создавать профиль при регистрации пользователя с помощью сигналов?
Определите сигнал в signals.py в приложении accounts:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
Не забудьте зарегистрировать сигнал в apps.py:
class AccountsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'accounts'
def ready(self):
import accounts.signals
Как измерить время выполнения запроса с помощью Middleware?
Создайте класс в middleware.py:
import time
from django.http import HttpResponse
class TimingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start = time.time()
response = self.get_response(request)
elapsed = time.time() - start
print(f"Запрос обработан за {elapsed:.2f} сек")
return response
Добавьте 'myapp.middleware.TimingMiddleware' в MIDDLEWARE в settings.py.
Дополнительные примеры с кодом и результатами
Пример 1: Кастомный тег шаблона для форматирования даты
Создайте файл blog/templatetags/blog_extras.py:
from django import template
from django.utils import timezone
register = template.Library()
@register.simple_tag
def current_time(format_string):
return timezone.now().strftime(format_string)
Использование в шаблоне:
{% load blog_extras %}
<p>Текущее время: {% current_time "%d.%m.%Y %H:%M" %}</p>
Результат на странице:
<p>Текущее время: 14.02.2025 15:30</p>
Пример 2: Фильтр шаблона для обрезания текста до заданного числа слов
@register.filter(name='truncate_words')
def truncate_words(value, arg):
words = value.split()
if len(words) > arg:
return ' '.join(words[:arg]) + '...'
return value
Шаблонный код:
{{ post.content|truncate_words:20 }}
Результат для длинного текста:
Первые двадцать слов текста... (остальное обрезано)
Пример 3: Сериализация в DRF с дополнительными действиями (кастомный endpoint)
from rest_framework.decorators import action
from rest_framework.response import Response
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
@action(detail=True, methods=['post'])
def like(self, request, pk=None):
post = self.get_object()
# логика лайка
return Response({'status': 'ok', 'likes': post.likes})
Запрос к /api/posts/1/like/ (POST) вернет JSON:
{"status": "ok", "likes": 5}
Пример 4: Работа с сессиями и куки
Представление, которое увеличивает счетчик посещений страницы:
def counter(request):
count = request.session.get('visits', 0) + 1
request.session['visits'] = count
return render(request, 'counter.html', {'count': count})
Шаблон:
<p>Вы посетили эту страницу {{ count }} раз.</p>
Результат после первого запроса:
Вы посетили эту страницу 1 раз.
Пример 5: Использование кастомного менеджера модели
Создайте менеджер, возвращающий только опубликованные посты (если добавить поле published):
class PublishedManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(published=True)
class Post(models.Model):
# ... поля
published = models.BooleanField(default=False)
objects = models.Manager() # стандартный менеджер
published_objects = PublishedManager() # кастомный
Использование в представлении:
Post.published_objects.all()
SQL-запрос будет содержать WHERE published = 1.
Пример 6: Обработка форм с загрузкой изображений
Модель с полем ImageField:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(upload_to='avatars/')
Форма:
from django import forms
from .models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['avatar']
Представление с обработкой POST и файла:
def upload_avatar(request):
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES, instance=request.user.profile)
if form.is_valid():
form.save()
return redirect('profile')
else:
form = ProfileForm(instance=request.user.profile)
return render(request, 'upload.html', {'form': form})
Результат: файл сохраняется в MEDIA_ROOT/avatars/.