vault backup: 2026-05-31 10:08:46
This commit is contained in:
Vendored
+55
-6
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@ type: concept
|
||||
tags: [django, backend, orm, database, migrations]
|
||||
created: 2026-05-30
|
||||
updated: 2026-05-31
|
||||
title: "Django: Модели и ORM"
|
||||
title: Django Модели и ORM
|
||||
source: ["[[lec1-django_start_models-1.pdf]]", "[[lec4-django_lec_queries.pdf]]", "[[p1-django-1.pdf]]"]
|
||||
---
|
||||
|
||||
@@ -18,6 +18,16 @@ source: ["[[lec1-django_start_models-1.pdf]]", "[[lec4-django_lec_queries.pdf]]"
|
||||
- `urls.py`: Описание маршрутов.
|
||||
- `models.py`: Определение таблиц БД.
|
||||
|
||||
```text
|
||||
project/
|
||||
├── manage.py
|
||||
├── project/
|
||||
│ ├── settings.py
|
||||
│ └── urls.py
|
||||
└── app/
|
||||
└── models.py
|
||||
```
|
||||
|
||||
## Определение моделей
|
||||
```python
|
||||
from django.db import models
|
||||
@@ -45,10 +55,24 @@ class Person(models.Model):
|
||||
- `FileField` — путь к загруженному файлу.
|
||||
- `ImageField` — файл изображения с дополнительной проверкой формата.
|
||||
|
||||
```python
|
||||
class Article(models.Model):
|
||||
id = models.AutoField(primary_key=True)
|
||||
title = models.CharField(max_length=200)
|
||||
body = models.TextField()
|
||||
views = models.IntegerField(default=0)
|
||||
price = models.DecimalField(max_digits=10, decimal_places=2)
|
||||
is_published = models.BooleanField(default=False)
|
||||
published_at = models.DateTimeField(null=True, blank=True)
|
||||
author_email = models.EmailField()
|
||||
attachment = models.FileField(upload_to="files/", blank=True)
|
||||
cover = models.ImageField(upload_to="covers/", blank=True)
|
||||
```
|
||||
|
||||
### Отношения
|
||||
- `ForeignKey(Target, on_delete=...)` — связь «один ко многим»: у одной записи `Target` может быть много связанных записей текущей модели.
|
||||
- `OneToOneField(Target, on_delete=...)` — связь «один к одному»: каждой записи соответствует максимум одна связанная запись.
|
||||
- `ManyToManyField(Target)` — связь «многие ко многим»: записи обеих моделей могут ссылаться на несколько записей другой модели.
|
||||
- `ForeignKey(Target, on_delete=...)` — связь "один ко многим": у одной записи `Target` может быть много связанных записей текущей модели.
|
||||
- `OneToOneField(Target, on_delete=...)` — связь "один к одному": каждой записи соответствует максимум одна связанная запись.
|
||||
- `ManyToManyField(Target)` — связь "многие ко многим": записи обеих моделей могут ссылаться на несколько записей другой модели.
|
||||
|
||||
`on_delete` задаёт, что делать с текущей записью, если удаляется связанная запись `Target`:
|
||||
- `CASCADE` — удалить текущую запись вместе со связанной.
|
||||
@@ -57,6 +81,22 @@ class Person(models.Model):
|
||||
- `SET_DEFAULT` — записать значение по умолчанию; требует `default`.
|
||||
- `DO_NOTHING` — ничего не делать на уровне Django, ответственность остаётся на БД и разработчике.
|
||||
|
||||
```python
|
||||
class Author(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
|
||||
class Profile(models.Model):
|
||||
author = models.OneToOneField(Author, on_delete=models.CASCADE)
|
||||
bio = models.TextField()
|
||||
|
||||
|
||||
class Book(models.Model):
|
||||
title = models.CharField(max_length=200)
|
||||
author = models.ForeignKey(Author, on_delete=models.PROTECT)
|
||||
co_authors = models.ManyToManyField(Author, related_name="coauthored_books", blank=True)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Миграции
|
||||
@@ -79,6 +119,22 @@ Django QuerySet ленивы (вычисляются только при обр
|
||||
- **Update:** `Person.objects.filter(id=1).update(age=25)`.
|
||||
- **Delete:** `obj.delete()` или `QuerySet.delete()`.
|
||||
|
||||
```python
|
||||
# Create
|
||||
person = Person.objects.create(first_name="Ivan", age=25)
|
||||
|
||||
# Read
|
||||
people = Person.objects.all()
|
||||
person = Person.objects.get(id=1)
|
||||
adults = Person.objects.filter(age__gte=18)
|
||||
|
||||
# Update
|
||||
Person.objects.filter(id=1).update(age=26)
|
||||
|
||||
# Delete
|
||||
person.delete()
|
||||
```
|
||||
|
||||
### Поиск по полям (Field Lookups)
|
||||
- `exact`, `iexact` (регистронезависимо).
|
||||
- `gt` (>), `gte` (>=), `lt` (<), `lte` (<=).
|
||||
@@ -86,22 +142,67 @@ Django QuerySet ленивы (вычисляются только при обр
|
||||
- `in` (список), `range` (диапазон).
|
||||
- `isnull=True`.
|
||||
|
||||
```python
|
||||
Person.objects.filter(first_name__exact="Ivan")
|
||||
Person.objects.filter(first_name__iexact="ivan")
|
||||
Person.objects.filter(age__gt=18)
|
||||
Person.objects.filter(age__range=(18, 30))
|
||||
Person.objects.filter(first_name__icontains="iv")
|
||||
Person.objects.filter(id__in=[1, 2, 3])
|
||||
Person.objects.filter(bio__isnull=True)
|
||||
```
|
||||
|
||||
### Оптимизация запросов
|
||||
- `select_related('field')` — заранее подтягивает связанную запись через `JOIN`. Подходит для `ForeignKey` и `OneToOneField`, когда у объекта есть одна связанная запись.
|
||||
- `prefetch_related('field')` — делает отдельный запрос за связанными объектами и собирает их в Python. Подходит для `ManyToManyField` и обратных связей, где связанных записей может быть много.
|
||||
- **Проблема N+1** — ситуация, когда Django делает один запрос за списком объектов, а потом ещё по одному запросу на каждый объект в цикле.
|
||||
|
||||
Пример: если вывести 100 книг и для каждой обратиться к `book.author`, без оптимизации может получиться 101 запрос. С `select_related('author')` авторы будут загружены сразу.
|
||||
```python
|
||||
# select_related: книга + её автор загружаются одним SQL-запросом
|
||||
books = Book.objects.select_related("author")
|
||||
|
||||
for book in books:
|
||||
print(book.title, book.author.name)
|
||||
```
|
||||
|
||||
```python
|
||||
# prefetch_related: авторы загружаются отдельно, затем Django связывает их с книгами
|
||||
books = Book.objects.prefetch_related("authors")
|
||||
|
||||
for book in books:
|
||||
print(book.title, [author.name for author in book.authors.all()])
|
||||
```
|
||||
|
||||
### Агрегация и аннотация
|
||||
- `aggregate(Avg('rating'))` — считает одно итоговое значение по всей выборке: среднее, сумму, минимум, максимум, количество. Возвращает словарь, а не QuerySet.
|
||||
- `annotate(total=Count('entries'))` — добавляет вычисляемое поле к каждому объекту в выборке.
|
||||
|
||||
Пример: `Book.objects.aggregate(Avg('rating'))` вернёт средний рейтинг всех книг. `Author.objects.annotate(total=Count('books'))` добавит каждому автору поле `total` с количеством его книг.
|
||||
```python
|
||||
from django.db.models import Avg, Count
|
||||
|
||||
# aggregate: одно итоговое значение по всей таблице книг
|
||||
result = Book.objects.aggregate(avg_rating=Avg("rating"))
|
||||
print(result["avg_rating"])
|
||||
|
||||
# annotate: вычисляемое поле для каждого автора
|
||||
authors = Author.objects.annotate(total_books=Count("books"))
|
||||
|
||||
for author in authors:
|
||||
print(author.name, author.total_books)
|
||||
```
|
||||
|
||||
### Логические условия
|
||||
- `Q-объекты` нужны для сложных условий в `filter()`: `OR` (`|`), `AND` (`&`), `NOT` (`~`).
|
||||
- `F-выражения` позволяют сравнивать и изменять поля прямо на стороне БД, не загружая значение в Python.
|
||||
|
||||
Пример `Q`: найти книги, где рейтинг выше 4 или название содержит `Django`.
|
||||
Пример `F`: увеличить счётчик просмотров на 1 прямо в БД: `views = F('views') + 1`.
|
||||
```python
|
||||
from django.db.models import F, Q
|
||||
|
||||
# Q: рейтинг выше 4 или название содержит Django
|
||||
books = Book.objects.filter(
|
||||
Q(rating__gt=4) | Q(title__icontains="Django")
|
||||
)
|
||||
|
||||
# F: увеличить счётчик просмотров прямо в БД
|
||||
Book.objects.filter(id=1).update(views=F("views") + 1)
|
||||
```
|
||||
|
||||
@@ -3,8 +3,8 @@ status: seed
|
||||
type: concept
|
||||
tags: [django, routing, templates, cbv, fbv]
|
||||
created: 2026-05-30
|
||||
updated: 2026-05-30
|
||||
title: Django: Представления, шаблоны и CBV
|
||||
updated: 2026-05-31
|
||||
title: "Django: Представления и Шаблоны"
|
||||
source: ["[[lec2-django_lec_urls_views_templates-1.pdf]]", "[[lec3-django_cbv-1.pdf]]", "[[p4-django_cbv-1.pdf]]"]
|
||||
---
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ status: seed
|
||||
type: concept
|
||||
tags: [django, forms, crud, validation, modelform]
|
||||
created: 2026-05-30
|
||||
updated: 2026-05-30
|
||||
title: "Django: Работа с формами и CUD"
|
||||
updated: 2026-05-31
|
||||
title: "Django: Формы и CUD"
|
||||
source: ["[[lec5-django_cud_form.pdf]]"]
|
||||
---
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ tags:
|
||||
- programming
|
||||
- python
|
||||
created: 2026-05-30
|
||||
updated: 2026-05-30
|
||||
updated: 2026-05-31
|
||||
title: Python - MOC
|
||||
---
|
||||
|
||||
@@ -19,7 +19,6 @@ title: Python - MOC
|
||||
|
||||
## Библиотеки и инструменты
|
||||
|
||||
|
||||
## Связанные заметки
|
||||
|
||||
- [[Programming - MOC]]
|
||||
|
||||
@@ -3,14 +3,14 @@ status: seed
|
||||
type: concept
|
||||
tags: [python, syntax, programming-basics, functional-programming]
|
||||
created: 2026-05-30
|
||||
updated: 2026-05-30
|
||||
title: Python: Базовый синтаксис и основы
|
||||
updated: 2026-05-31
|
||||
title: Основы Python
|
||||
source: ["[[50-python-lec.pdf]]"]
|
||||
---
|
||||
|
||||
# Основы Python
|
||||
|
||||
**Python** — высокоуровневый объектно-ориентированный язык программирования с «двумерным синтаксисом» (структура определяется отступами).
|
||||
**Python** — высокоуровневый объектно-ориентированный язык программирования с "двумерным синтаксисом" (структура определяется отступами).
|
||||
|
||||
## Вывод и ввод данных
|
||||
- **Вывод:** `print("текст", sep=" ", end="\n")`.
|
||||
|
||||
@@ -3,8 +3,8 @@ status: seed
|
||||
type: concept
|
||||
tags: [python, oop, classes, inheritance, polymorphism, encapsulation]
|
||||
created: 2026-05-30
|
||||
updated: 2026-05-30
|
||||
title: Основы объектно-ориентированного программирования
|
||||
updated: 2026-05-31
|
||||
title: Основы ООП в Python
|
||||
source: ["[[oop.pdf]]"]
|
||||
---
|
||||
|
||||
@@ -15,8 +15,8 @@ source: ["[[oop.pdf]]"]
|
||||
## Четыре столпа ООП
|
||||
1. **Абстракция:** Выделение ключевых характеристик объекта и отсечение незначимых.
|
||||
2. **Инкапсуляция:** Сокрытие внутренней логики и данных. В Python реализуется соглашением об именовании:
|
||||
- `_name`: «защищенный» (не рекомендуется трогать вне класса).
|
||||
- `__name`: «приватный» (имя искажается для предотвращения прямого доступа).
|
||||
- `_name`: "защищенный" (не рекомендуется трогать вне класса).
|
||||
- `__name`: "приватный" (имя искажается для предотвращения прямого доступа).
|
||||
3. **Наследование:** Создание новых классов на базе существующих. Все классы наследуются от `object`.
|
||||
4. **Полиморфизм:** Возможность использовать разные типы данных через единый интерфейс.
|
||||
- *Полиморфизм подтипов:* Использование потомка вместо родителя.
|
||||
|
||||
Reference in New Issue
Block a user