Почему Django использует внутренний класс `Meta` в моделях?

Если я хочу описать некоторую информацию, такую как упорядочивание, если модель прокси или абстрактная, какие поля должны быть уникальными вместе, то мне нужно поместить эту информацию в класс с именем Meta, который находится внутри класса моей модели. Но если я хочу изменить менеджер, я помещаю информацию об этом в сам класс модели

class Product(models.Model):
    class Meta:
         unique_together = ...
         ordering = ...
    objects = My manager()

Почему разработчики Django приняли такое дизайнерское решение (заставляя помещать некоторую информацию о модели во внутренний класс Meta, а не в сам класс модели)? Почему они просто не позволили мне поместить "ordering", "uniwue_tpgether" в сам класс модели?

EDIT: Anentropic прокомментировал, что это своего рода namespacing. Я подумал об этом во время создания вопроса. Если внутренний класс Meta является способом размещения метаинформации о модели, чтобы я мог свободно создавать поля в самом классе модели, тогда почему атрибут objects не был помещен в класс Meta? Есть много других атрибутов (save, refresh_from_db, get_deffered_fields и more), которые существуют в самом классе модели, а не в классе Meta, которые могут столкнуться с именами моих полей, если я о них не знаю.

Возможно, это делается для того, чтобы избежать конфликтов с именами полей. Например, поместив ordering в класс Meta, вы все равно можете иметь поле с именем ordering в вашей модели.

Но тогда почему менеджер, названный в примере objects, не находится также в Meta? Причина, вероятно, в том, что вы можете обращаться к нему как к Product.objects, что не похоже на любое другое поле Meta. Более того, менеджер может иметь пользовательское имя, например Product.products.

Вы упомянули, что могут возникнуть конфликты и с другими атрибутами класса, помимо мета-полей, например, с методами. Это правда, как упоминается в документации:

Будьте осторожны, чтобы не выбрать имена полей, которые конфликтуют с API моделей , например clean, save или delete.

Риск конфликта здесь довольно мал, потому что методы обычно имеют глагол в своем имени, например save или get, тогда как имена полей обычно являются существительными, например name, id или price.

Вернуться на верх