💻 Примеры: Django-блок в одном месте

🎯 Типовые паттерны К оглавлению урока

⚡ Ключевые примеры

# Минимальная модель
from django.db import models
class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)

# Регистрация в admin
from django.contrib import admin
from .models import Book
admin.site.register(Book)

# Запуск: makemigrations -> migrate -> runserver

Пример 1: Полная модель с текстовыми полями

Пример из лекции — модель Book со всеми текстовыми типами полей:

# myapp/models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)                         # Название книги
    author = models.CharField(max_length=100)                        # Имя автора
    description = models.TextField(blank=True, null=True)            # Описание
    contact_email = models.EmailField(max_length=254, blank=True, null=True)  # Email
    slug = models.SlugField(max_length=100, blank=True, null=True)   # URL-метка
    website = models.URLField(max_length=200, blank=True, null=True) # Сайт

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['title']
        verbose_name = 'Книга'
        verbose_name_plural = 'Книги'

Пример 2: Модель Author с числовыми полями

# myapp/models.py
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()
    net_worth = models.BigIntegerField()
    positive_reviews = models.PositiveIntegerField()
    books_published = models.PositiveSmallIntegerField()
    years_experience = models.SmallIntegerField()
    rating = models.FloatField()
    average_income = models.DecimalField(max_digits=10, decimal_places=2)

    def __str__(self):
        return self.name

Пример 3: Связи между моделями

# myapp/models.py
from django.db import models
from django.contrib.auth.models import User

# ForeignKey — многие книги принадлежат одному автору
class Author(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(
        Author,
        on_delete=models.CASCADE,
        related_name='books'
    )
    published_date = models.DateField()

    def __str__(self):
        return self.title

# ManyToManyField — книга может иметь множество тегов
class Tag(models.Model):
    name = models.CharField(max_length=50, unique=True)

    def __str__(self):
        return self.name

class Article(models.Model):
    title = models.CharField(max_length=200)
    tags = models.ManyToManyField(Tag, blank=True, related_name='articles')

    def __str__(self):
        return self.title

# OneToOneField — расширение профиля пользователя
class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    bio = models.TextField(blank=True)
    avatar = models.ImageField(upload_to='avatars/', blank=True, null=True)

    def __str__(self):
        return f"Профиль {self.user.username}"

Пример 4: Настройка Admin через ModelAdmin

# myapp/admin.py
from django.contrib import admin
from .models import Book, Author, Tag

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    list_display = ['name']
    search_fields = ['name']

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ['title', 'author', 'published_date']
    search_fields = ['title', 'author__name']
    list_filter = ['published_date', 'author']
    ordering = ['-published_date']
    date_hierarchy = 'published_date'

@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
    list_display = ['name']
    search_fields = ['name']

Пример 5: Файл settings.py — минимальная конфигурация

# config/settings.py
from pathlib import Path
from environ import Env  # pip install django-environ

BASE_DIR = Path(__file__).resolve().parent.parent

env = Env()
Env.read_env(BASE_DIR / '.env')

# Безопасность
SECRET_KEY = env('SECRET_KEY')   # Из .env, не в коде!
DEBUG = env.bool('DEBUG', default=False)
ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=['localhost', '127.0.0.1'])

# Приложения
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp.apps.MyappConfig',
]

# База данных
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

# Тип первичного ключа по умолчанию
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# Локализация
LANGUAGE_CODE = 'ru-ru'
TIME_ZONE = 'Europe/Moscow'
USE_I18N = True
USE_TZ = True

Пример 6: Простое View и URL-маршрут

# myapp/views.py
from django.http import HttpResponse

def hello_world(request):
    return HttpResponse("<h1>Hello, Django!</h1>")

# myapp/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('hello/', views.hello_world, name='hello_world'),
]

# config/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls')),
]

Пример 7: Добавление поля в существующую модель

# Исходная модель
class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)

# После добавления нового поля — ОБЯЗАТЕЛЬНО указываем null=True или default
class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    published_date = models.DateField(null=True, blank=True)  # Новое поле

# Затем создаём и применяем миграцию
# python manage.py makemigrations
# python manage.py migrate