Как в Django создать модель, для которой не будет создаваться таблица в базе данных

Ответ

Чтобы Django не управлял таблицей для модели, необходимо в её внутреннем классе Meta установить атрибут managed = False.

Это полезно в следующих случаях:

  • Для работы с уже существующими таблицами или представлениями (views), которые управляются вне Django.
  • Для создания моделей-прокси над сложными SQL-запросами.
  • Для интеграции с legacy-базами данных.

Пример:

from django.db import models

class DatabaseView(models.Model):
    # Поля модели должны соответствовать столбцам представления
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=255)
    total = models.DecimalField(max_digits=10, decimal_places=2)

    class Meta:
        # Указываем Django, что он не должен создавать, изменять или удалять
        # таблицу для этой модели. Команда migrate проигнорирует её.
        managed = False
        # Явно указываем имя существующей таблицы или представления
        db_table = 'my_existing_database_view'

Важные моменты:

  • При managed = False вы несёте полную ответственность за создание и обновление схемы таблицы.
  • Django-миграции не будут генерироваться для таких моделей.

Ответ 18+ 🔞

А, ну это же про ту самую магию, когда ты говоришь Джанге: «Слушай, дружище, тут есть табличка, но ты, пожалуйста, не лезь, она уже взрослая и сама всё умеет».

Вот смотри, чтобы Джанга не полезла со своими миграциями и советами, как жить, в таблицу твоей модели, надо в её внутреннем классе Meta поставить флажок managed = False.

Зачем это, спрашивается, надо? Да вариантов — овердохуища! Например:

  • У тебя уже есть готовая таблица, с которой кто-то другой нянчится, а ты хочешь просто через Джангу с ней общаться.
  • Или ты наколдовал какое-нибудь хитрое SQL-представление (view), а теперь хочешь притвориться, что это обычная модель.
  • Или ты интегрируешься со старой базой, которая видала виды, и там свои порядки.

Вот, смотри, как это выглядит в коде:

from django.db import models

class DatabaseView(models.Model):
    # Поля модели должны соответствовать столбцам представления
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=255)
    total = models.DecimalField(max_digits=10, decimal_places=2)

    class Meta:
        # Вот этой строчкой ты говоришь Джанге: "Руки прочь от схемы!"
        # Мол, миграции — это не про нас, мы тут просто гости.
        managed = False
        # И явно указываешь имя существующей таблицы или view, чтобы не гадал.
        db_table = 'my_existing_database_view'

Но запомни раз и навсегда, ёпта:

  • Как только ты поставил managed = False, вся ответственность за то, чтобы таблица существовала и была в адекватном состоянии, ложится на твои, прости господи, плечи. Джанга пальцем о палец не ударит, чтобы её создать или изменить.
  • Команда migrate на такую модель посмотрит, вежливо кивнёт и пройдёт мимо. Никаких операций со схемой базы она генерировать не будет. Всё, пиздец, ты сам себе хозяин.