Разработка веб-приложения на Django: полный цикл с практическими примерами

Раздел: Веб-фреймворки -> Веб-разработка

Базовое создание приложения на Django (MVT)

Наиболее эффективное решение: использование стандартного подхода MVT (Model-View-Template)

Django предоставляет встроенную архитектуру, которая делит приложение на модели (работа с базой данных), представления (логика обработки запроса) и шаблоны (отображение). Этот подход подходит для большинства типовых проектов благодаря минимальной настройке и высокой скорости разработки.

  1. Установка Django:
    pip install django

    Html css js python (интеграция python с html, css, javascript)

  2. Создание проекта:
    django-admin startproject mysite

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

    – появится папка с файлами settings.py, urls.py и др.
  3. Создание приложения:
    python manage.py startapp myapp

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

    – внутри проекта появляется папка myapp с файлами models.py, views.py, admin.py и др.
  4. Определение модели в models.py:
    from django.db import models
    
    class Article(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)

  5. Регистрация модели в админке (admin.py):
    from django.contrib import admin
    from .models import Article
    
    @admin.register(Article)
    class ArticleAdmin(admin.ModelAdmin):
        list_display = ('title', 'pub_date')

    Python web server (web-сервер на python)

  6. Выполнение миграций:
    python manage.py makemigrations
    python manage.py migrate

    Python 3 веб приложение (веб-приложение на python 3)

  7. Создание представления в views.py (функциональное представление):
    from django.shortcuts import render
    from .models import Article
    
    def article_list(request):
        articles = Article.objects.all()
        return render(request, 'myapp/article_list.html', {'articles': articles})

    Python веб сервисы (веб-сервисы на python)

  8. Настройка маршрута в urls.py приложения:
    from django.urls import path
    from . import views
    
    urlpatterns = [
        path('', views.article_list, name='article_list'),
    ]

    примеры python веб (примеры веб-разработки на python)

  9. Подключение маршрутов приложения в корневом urls.py:
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('articles/', include('myapp.urls')),
    ]

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

  10. Создание шаблона myapp/templates/myapp/article_list.html:
    
    
    Статьи
    
    

    Список статей

    {% for article in articles %}

    {{ article.title }}

    {{ article.content|truncatewords:30 }}


    {% empty %}

    Нет статей.

    {% endfor %}

    Django python создание приложения (создание веб-приложения на django)

  11. Запуск сервера разработки:
    python manage.py runserver

    библиотека django python (библиотека django для веб-разработки на python)

    – приложение доступно по адресу http://127.0.0.1:8000/articles/.

Цели и случаи использования:

  • Быстрая разработка прототипов и MVP.
  • Проекты с классической клиент-серверной архитектурой, где весь вывод формируется на стороне сервера.
  • Сайты с админ-панелью для управления контентом.

Как создать веб-приложение с использованием Class-Based Views (CBV) вместо функций?

Class-Based Views упрощают реализацию повторяющихся паттернов (список, детальная страница, создание, обновление) и предоставляют готовые классы-миксины. Пример для списка статей:

from django.views.generic import ListView
from .models import Article

class ArticleListView(ListView):
    model = Article
    template_name = 'myapp/article_list.html'
    context_object_name = 'articles'

Python django практика (практика django на python)

В urls.py подключаем:

path('', views.ArticleListView.as_view(), name='article_list')

Python index html (работа с index.html в python)

Цель: сокращение объёма кода для стандартных операций, удобство наследования.

Как организовать REST API на Django с помощью Django REST Framework?

Для создания JSON API добавляем DRF. Установка:

pip install djangorestframework
. Добавляем 'rest_framework' в INSTALLED_APPS. Создаём сериализаторы:

# myapp/serializers.py
from rest_framework import serializers
from .models import Article

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = '__all__'

Представление (ViewSet):

from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer

class ArticleViewSet(viewsets.ModelViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticleSerializer

Маршруты через DefaultRouter:

from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'articles', ArticleViewSet)
urlpatterns = router.urls

Теперь API доступен по /articles/ (GET, POST, PUT, DELETE, etc).

Цель: обеспечить взаимодействие с мобильными приложениями, SPA, внешними интеграциями.

Как обрабатывать длительные задачи асинхронно с Celery и Redis?

Для задач типа отправки писем или генерации отчётов используем Celery. Установка:

pip install celery[redis]
. Создаём файл celery.py в проекте:

# mysite/celery.py
import os
from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
app = Celery('mysite')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

В __init__.py импортируем:

from .celery import app as celery_app
.

Определяем задачу в myapp/tasks.py:

from celery import shared_task
from django.core.mail import send_mail

@shared_task
def send_article_notification(article_id):
    # логика отправки
    print(f'Notification sent for article {article_id}')

Запуск Celery worker:

celery -A mysite worker --loglevel=info
.

В представлении вызываем задачу отложенно:

from .tasks import send_article_notification

# при создании статьи
send_article_notification.delay(article.id)

Цель: повысить отзывчивость веб-сервера, обрабатывая тяжёлые операции в фоне.

Как изолировать среду разработки с помощью Docker и Docker Compose?

Создаём Dockerfile:

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["gunicorn", "mysite.wsgi:application", "--bind", "0.0.0.0:8000"]

Файл docker-compose.yml:

version: '3'
services:
  web:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      - db
  db:
    image: postgres:15
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass

Запуск:

docker-compose up
. Django настраивается для PostgreSQL через переменные окружения.

Цель: одинаковые окружения на всех машинах, упрощение деплоя и тестирования.

Типичные проблемы и их решения

Как избежать ошибки "RuntimeError: Model class apps.myapp.models.Article doesn't declare an explicit app_label"?

Причина: модель определена вне приложения или неправильно подключено приложение в INSTALLED_APPS. Решение: убедиться, что приложение добавлено в settings.py как 'myapp'.

Как исправить ошибку "django.db.utils.IntegrityError: NOT NULL constraint failed" при миграциях?

Причина: добавление поля с null=False на существующую таблицу без значения по умолчанию. Решение: указать default или null=True, затем выполнить миграции.

Почему статические файлы (CSS, JS) не отображаются в production?

Причина: Django по умолчанию не обслуживает статику вне режима DEBUG. Решение: настроить STATIC_ROOT и запустить collectstatic, а также настроить веб-сервер (Nginx) на раздачу статики.

Как решить проблему "DisallowedHost at /" при развёртывании?

Причина: HOST заголовок не совпадает с ALLOWED_HOSTS. Решение: добавить домен или IP в список ALLOWED_HOSTS в settings.py.

Расширенные примеры кода и команд

1. Использование Generic Class-Based Views с дополнительными контекстными данными

Пример добавления дополнительных данных в шаблон через переопределение get_context_data:

Пример
from django.views.generic import ListView
from .models import Article, Category

class ArticleListView(ListView):
    model = Article
    template_name = 'myapp/article_list.html'
    context_object_name = 'articles'
    paginate_by = 10

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['categories'] = Category.objects.all()
        context['current_category'] = self.request.GET.get('category', 'all')
        return context

В шаблоне можно использовать {{ categories }} и {{ current_category }}. Результат – список статей с пагинацией и боковой панелью категорий.

2. Форма с валидацией и сохранением данных (ModelForm)

Пример
# myapp/forms.py
from django import forms
from .models import Article

class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ['title', 'content']
        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}),
        }

Представление для создания статьи:

Пример
from django.shortcuts import render, redirect
from .forms import ArticleForm

def create_article(request):
    if request.method == 'POST':
        form = ArticleForm(request.POST)
        if form.is_valid():
            article = form.save()
            return redirect('article_detail', pk=article.pk)
    else:
        form = ArticleForm()
    return render(request, 'myapp/article_form.html', {'form': form})

Шаблон article_form.html:

Пример
{% csrf_token %} {{ form.as_p }}

Результат: после отправки формы создаётся запись в базе и происходит перенаправление.

3. Кастомная команда управления (management command)

Создаём задачу импорта статей из CSV. Структура: myapp/management/commands/import_articles.py:

Пример
import csv
from django.core.management.base import BaseCommand
from myapp.models import Article

class Command(BaseCommand):
    help = 'Импортирует статьи из CSV файла'

    def add_arguments(self, parser):
        parser.add_argument('file_path', type=str)

    def handle(self, *args, **options):
        file_path = options['file_path']
        with open(file_path, newline='', encoding='utf-8') as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                Article.objects.create(
                    title=row['title'],
                    content=row['content']
                )
        self.stdout.write(self.style.SUCCESS('Импорт завершён'))

Запуск команды:

Пример
python manage.py import_articles data/articles.csv

Результат: в консоли увидим сообщение об успешном импорте.

4. Асинхронная отправка письма с вложением через Celery

Пример
# myapp/tasks.py
from celery import shared_task
from django.core.mail import EmailMessage
from django.contrib.auth.models import User

@shared_task
def send_file_mail(user_id, file_path):
    user = User.objects.get(id=user_id)
    email = EmailMessage(
        subject='Ваш отчёт',
        body='Во вложении находится сгенерированный документ.',
        from_email='noreply@example.com',
        to=[user.email],
    )
    with open(file_path, 'rb') as f:
        email.attach('report.pdf', f.read(), 'application/pdf')
    email.send()
    return f'Email sent to {user.email}'

Вызов из представления:

Пример
send_file_mail.delay(request.user.id, '/tmp/report.pdf')

Worker выведет лог об отправке.

5. Работа с загрузкой файлов (изображения)

Модель:

Пример
class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    image = models.ImageField(upload_to='articles/', blank=True, null=True)

Настройка в settings.py:

Пример
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

В корневом urls.py для разработки:

Пример
from django.conf import settings
from django.conf.urls.static import static

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Форма с файлом:

Пример
class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = ['title', 'content', 'image']

В шаблоне enctype="multipart/form-data":

Пример
{% csrf_token %} {{ form.as_p }}

Результат: загруженные изображения будут доступны через /media/articles/имя_файла.

6. Кастомизация панели администратора с использованием ModelAdmin

Пример
class ArticleAdmin(admin.ModelAdmin):
    list_display = ('title', 'pub_date', 'is_published')
    list_filter = ('pub_date', 'is_published')
    search_fields = ('title', 'content')
    date_hierarchy = 'pub_date'
    ordering = ('-pub_date',)
    actions = ['make_published']

    def make_published(self, request, queryset):
        queryset.update(is_published=True)
    make_published.short_description = 'Опубликовать выбранные статьи'

Результат: в админке появится кнопка массовой публикации и удобные фильтры.

Создание веб-приложения на Django - comments

En
Django python создание приложения (python)