Skip to content

Latest commit

 

History

History
308 lines (193 loc) · 9.62 KB

File metadata and controls

308 lines (193 loc) · 9.62 KB

Модуль 3. Урок 18. Сортировка, изменение и удаление записей в Django ORM

В этом уроке мы научимся:

  • сортировать данные в Django ORM;
  • изменять записи в базе;
  • выполнять массовые обновления;
  • удалять записи с помощью ORM-запросов;

Вспомним базу

На предыдущем уроке мы научились выбирать данные из базы и фильтровать их по нужным условиям.

Теперь мы сделаем следующий шаг — научимся управлять этими данными: изменять, сортировать и удалять.

Для примеров будем использовать модель Movie из проекта CinemaHub:

class Movie(models.Model):
    title = models.CharField(max_length=100)
    year = models.PositiveIntegerField()
    rating = models.FloatField(default=0)
    is_published = models.BooleanField(default=True)
    time_create = models.DateTimeField(auto_now_add=True)
    time_update = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

Сортировка записей — метод order_by()

Иногда нам нужно не просто вывести все фильмы, а сделать это в определённом порядке: по алфавиту, по рейтингу, по дате выхода и т.д.

Для этого в Django ORM используется метод order_by().

Сортировка по возрастанию

Movie.objects.order_by('title')

Такой запрос отсортирует все фильмы в алфавитном порядке (по возрастанию, ASC).

SQL-запрос при этом будет выглядеть так:

SELECT * FROM movies_movie ORDER BY title ASC;

Сортировка по убыванию

Чтобы отсортировать записи в обратном порядке, добавляем знак - перед именем поля:

Movie.objects.order_by('-rating')

Теперь фильмы будут выведены от самого высокого рейтинга к низкому.

SQL:

SELECT * FROM movies_movie ORDER BY rating DESC;

Сортировка с фильтрацией

Часто сортировка используется вместе с фильтрацией:

Movie.objects.filter(is_published=True).order_by('-year')

Такой запрос сначала отберёт опубликованные фильмы, а затем отсортирует их по году — от новых к старым.


Сортировка по умолчанию (в модели)

Если вы хотите, чтобы данные всегда возвращались в определённом порядке, можно задать сортировку прямо в модели:

class Movie(models.Model):
    ...
    class Meta:
        ordering = ['-time_create']

Теперь даже простой запрос:

Movie.objects.all()

будет автоматически отсортирован по дате создания (от новых к старым).


Практическая проверка

  1. Запустите Django shell:

    python manage.py shell_plus --print-sql
  2. Проверьте сортировку фильмов:

    Movie.objects.order_by('title')
    Movie.objects.order_by('-year')
  3. Затем откройте в браузере ваш список фильмов — убедитесь, что порядок отображения изменился.


Изменение записей

Иногда нужно обновить данные — например, изменить название фильма или исправить ошибку в годе выпуска.

Изменение одной записи

Получаем объект, изменяем поля, сохраняем изменения:

movie = Movie.objects.get(pk=2)
movie.title = 'Interstellar (2014)'
movie.rating = 9.0
movie.save()

SQL-запрос, который сгенерирует Django:

UPDATE movies_movie SET title = 'Interstellar (2014)', rating = 9.0 WHERE id = 2;

После этого обновите страницу в браузере — изменения должны отобразиться.


Массовое обновление — метод update()

Когда нужно обновить сразу несколько записей — используем update().

Например, сделаем все фильмы неопубликованными:

Movie.objects.update(is_published=False)

Или изменим статус только у фильмов до 2010 года:

Movie.objects.filter(year__lt=2010).update(is_published=True)

SQL-запрос:

UPDATE movies_movie SET is_published = 1 WHERE year < 2010;

Важно помнить

  • update() нельзя применять к отдельным объектам:

    Movie.objects.get(pk=1).update(is_published=False)  # Ошибка!
  • update() нельзя использовать со срезами:

    Movie.objects.all()[:3].update(is_published=True)  # Ошибка!

Метод работает только с QuerySet, то есть с выборкой, а не с отдельной записью.


Удаление записей

Теперь давайте научимся удалять данные.

Удаление выборки

Movie.objects.filter(year__lt=2000).delete()

SQL-запрос:

DELETE FROM movies_movie WHERE year < 2000;

Удаление всех записей

Movie.objects.all().delete()

Но использовать это стоит очень осторожно — команда удалит абсолютно все фильмы из таблицы.


Удаление одной записи

Если нужно удалить один конкретный фильм:

movie = Movie.objects.get(pk=5)
movie.delete()

После удаления можно проверить, что запись исчезла:

Movie.objects.filter(pk=5)
# <QuerySet []>

Проверка результата в браузере

После любого изменения — обновления или удаления — всегда полезно проверить данные визуально.

Например, если у вас есть представление:

def movies_list(request):
    movies = Movie.objects.filter(is_published=True).order_by('-year')
    return render(request, 'movies/movies_list.html', {'movies': movies})

После обновлений или удалений просто обновите страницу — и вы сразу увидите изменения, сделанные через ORM.


Практические задания

Задание 1. Сортировка

Выведите список всех фильмов, отсортированных по году выпуска по возрастанию.


Задание 2. Сортировка + фильтрация

Выведите только опубликованные фильмы (is_published=True), отсортировав их по названию.


Задание 3. Изменение данных

Найдите фильм с pk=3 и измените его рейтинг на 8.7.


Задание 4. Массовое обновление

Обновите флаг is_published на True для всех фильмов, выпущенных после 2015 года.


Задание 5. Удаление

Удалите все фильмы, у которых рейтинг меньше 5.


Задание 6. Проверка

После каждого шага откройте страницу со списком фильмов и убедитесь, что изменения действительно применились.


Вопросы

  1. Какой метод используется для сортировки записей в Django ORM?
  2. Как отсортировать записи по убыванию рейтинга?
  3. Что делает параметр ordering внутри класса Meta?
  4. Чем отличаются методы save() и update()?
  5. Почему update() нельзя использовать на одной записи?
  6. Как удалить все фильмы, год которых меньше 2010?
  7. Как проверить, что запись успешно удалена?
  8. Как можно задать сортировку “по умолчанию” для модели?
  9. Как обновить несколько записей одним запросом?
  10. Почему важно проверять изменения через браузер после выполнения ORM-запросов?

Предыдущий урок | Следующий урок