Auto | arch-x1: 2026-06-05 13:29:15
This commit is contained in:
@@ -8,7 +8,7 @@ tags:
|
||||
- database
|
||||
- migrations
|
||||
created: 2026-05-30
|
||||
updated: 2026-05-31
|
||||
updated: 2026-06-05
|
||||
source:
|
||||
- '[[lec1-django_start_models-1.pdf]]'
|
||||
- '[[lec4-django_lec_queries.pdf]]'
|
||||
@@ -77,6 +77,15 @@ class Article(models.Model):
|
||||
cover = models.ImageField(upload_to="covers/", blank=True)
|
||||
```
|
||||
|
||||
Если не указать `primary_key=True`, Django автоматически создаёт поле `id`. В современных версиях тип поля по умолчанию обычно задаётся настройкой `DEFAULT_AUTO_FIELD`, часто это `BigAutoField`.
|
||||
|
||||
`CharField` требует `max_length`, потому что БД должна знать максимальный размер строки.
|
||||
|
||||
`null=True` и `blank=True` — не одно и то же:
|
||||
|
||||
- `null=True` разрешает хранить `NULL` в базе данных;
|
||||
- `blank=True` разрешает оставлять поле пустым в формах и админке.
|
||||
|
||||
### Отношения
|
||||
- `ForeignKey(Target, on_delete=...)` — связь "один ко многим": у одной записи `Target` может быть много связанных записей текущей модели.
|
||||
- `OneToOneField(Target, on_delete=...)` — связь "один к одному": каждой записи соответствует максимум одна связанная запись.
|
||||
@@ -105,6 +114,32 @@ class Book(models.Model):
|
||||
co_authors = models.ManyToManyField(Author, related_name="coauthored_books", blank=True)
|
||||
```
|
||||
|
||||
`related_name` задаёт имя обратной связи. Если у книги есть `author = ForeignKey(Author, related_name="books")`, то у автора можно получить книги так:
|
||||
|
||||
```python
|
||||
author.books.all()
|
||||
```
|
||||
|
||||
Для `ManyToManyField` промежуточная модель задаётся через `through`, когда у самой связи есть дополнительные поля:
|
||||
|
||||
```python
|
||||
class Student(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
|
||||
|
||||
class Course(models.Model):
|
||||
title = models.CharField(max_length=100)
|
||||
students = models.ManyToManyField(Student, through="Enrollment")
|
||||
|
||||
|
||||
class Enrollment(models.Model):
|
||||
student = models.ForeignKey(Student, on_delete=models.CASCADE)
|
||||
course = models.ForeignKey(Course, on_delete=models.CASCADE)
|
||||
grade = models.IntegerField(null=True, blank=True)
|
||||
```
|
||||
|
||||
Связь можно менять методами `.add()`, `.remove()`, `.set()`, `.clear()`.
|
||||
|
||||
---
|
||||
|
||||
## Миграции
|
||||
@@ -214,3 +249,34 @@ books = Book.objects.filter(
|
||||
# F: увеличить счётчик просмотров прямо в БД
|
||||
Book.objects.filter(id=1).update(views=F("views") + 1)
|
||||
```
|
||||
|
||||
## Простыми словами для экзамена
|
||||
|
||||
Модель Django — это Python-класс, который описывает таблицу БД. Поле модели — это колонка таблицы. Объект модели — это строка таблицы.
|
||||
|
||||
`Class Meta` задаёт служебные настройки модели: сортировку, человекочитаемые имена, ограничения, имя таблицы.
|
||||
|
||||
Основные методы QuerySet:
|
||||
|
||||
- `.all()` — все объекты;
|
||||
- `.filter()` — несколько объектов по условию;
|
||||
- `.exclude()` — всё, кроме условия;
|
||||
- `.get()` — ровно один объект; если ноль или больше одного, будет ошибка;
|
||||
- `.order_by()` — сортировка;
|
||||
- `.count()` — количество;
|
||||
- `.exists()` — есть ли хотя бы одна запись;
|
||||
- `.distinct()` — убрать дубли;
|
||||
- `.aggregate()` — один итог по всей выборке, возвращает словарь;
|
||||
- `.annotate()` — добавляет вычисляемое поле каждому объекту.
|
||||
|
||||
Если нужно найти максимум цены по каждой категории, используют `annotate()` на категориях:
|
||||
|
||||
```python
|
||||
Category.objects.annotate(max_price=Max("product__price"))
|
||||
```
|
||||
|
||||
Если нужен один максимум по всем товарам, используют `aggregate()`:
|
||||
|
||||
```python
|
||||
Product.objects.aggregate(max_price=Max("price"))
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user