Разработка веб-приложений с использованием фреймворка Django и языка Python

Раздел: Python -> Веб-разработка

Основы создания веб-сайта на Django

Рассмотрим стандартный процесс разработки полноценного сайта на Django. Первый шаг - установка фреймворка через pip:

pip install django

создание сайтов python django (создание веб-сайтов на django с использованием python)

Далее создается проект и приложение:

django-admin startproject mysite
cd mysite
python manage.py startapp blog

Python 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.title

Python web flask (web-фреймворк flask)

Выполняем миграции:

python manage.py makemigrations
python manage.py migrate

Python 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 createsuperuser

Python веб сервисы (веб-сервисы на 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 runserver

Python 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/.

Создание веб-сайтов на Django с использованием Python - comments

En
создание сайтов python django (python)