Content type django что это
Как именно работают типы контента Django?
Мне действительно трудно понять концепцию типов контента Django. Это кажется очень хакерским и, в конечном счете, против того, как Python стремится что-то делать. При этом, если я собираюсь использовать Django, то я должен работать в рамках фреймворка.
Поэтому я прихожу сюда с вопросом, может ли кто-нибудь привести практический пример того, как работает тип контента и как вы его реализуете. Почти все учебники (в основном в блогах), которые я рассмотрел, не очень хорошо освещают эту концепцию. Похоже, они начинают с того места, где закончилась документация по Django (что похоже никуда).
Итак, вы хотите использовать инфраструктуру типов контента в своей работе?
Начните с того, что задайте себе вопрос: «Должны ли какие-либо из этих моделей быть связаны таким же образом с другими моделями, и / или я буду использовать эти отношения непредвиденными способами позже в будущем?» Причина, по которой мы задаем этот вопрос, заключается в том, что именно это делает структура типов контента лучше всего: она создает общие отношения между моделями. Бла-бла, давайте углубимся в некоторый код и посмотрим, что я имею в виду.
Итак, у нас есть способ теоретически создать эти отношения. Однако, как программист Python, ваш превосходный интеллект говорит вам, что это отстой, и вы можете добиться большего. Дай пять!
Войдите в структуру типов контента!
Бам! Точно так же вы можете работать с комментариями для этих двух моделей. На самом деле, давайте продолжим и сделаем это в нашей оболочке (введите python manage.py shell из вашей директории проекта Django).
Каковы другие практические последствия этих «общих» отношений?
Что если мы хотим добавить комментарии к этим песням? Ну, мы можем просто нарисовать общее отношение:
Это слишком хорошо, чтобы быть правдой?
В структуре типов контента есть нечто большее, чем я показал здесь. Существует целый уровень детализации и более подробное использование, но для среднего человека, по моему мнению, вы будете использовать его 9 из 10 раз.
Общие реляционеры (?) Будьте осторожны!
Фреймворк contenttypes ¶
Django включает contenttypes приложение, которое может отслеживать все модели, установленные в вашем проекте на базе Django, обеспечивая высокоуровневый универсальный интерфейс для работы с вашими моделями.
Обзор ¶
Экземпляры ContentType имеют методы для возврата классов моделей, которые они представляют, и для запроса объектов из этих моделей. ContentType также есть настраиваемый менеджер, который добавляет методы для работы ContentType и получения экземпляров ContentType для конкретной модели.
Отношения между вашими моделями, а ContentType также могут использоваться для включения «общих» отношений между экземпляром одной из ваших моделей и экземплярами любой установленной вами модели.
Установка фреймворка contenttypes ¶
Обычно рекомендуется установить фреймворк contenttypes; это требуется для некоторых других приложений Django:
ContentType Модель ¶
Каждый экземпляр ContentType имеет два поля, которые, вместе взятые, однозначно описывают установленную модель:
Дополнительно доступно следующее свойство:
Удобочитаемое имя типа контента. Это взято из verbose_name атрибута модели.
Давайте посмотрим на пример, чтобы увидеть, как это работает. Если у вас уже установлено contenttypes приложение, а затем добавьте его в настройки и запустите для его установки, модель будет установлена в вашу базу данных. Вместе с этим будет создан новый экземпляр со следующими значениями: the sites application INSTALLED_APPS manage.py migrate django.contrib.sites.models.Site ContentType
Методы на ContentType инстансах ¶
У каждого ContentType экземпляра есть методы, которые позволяют вам перейти от ContentType экземпляра к модели, которую он представляет, или получить объекты из этой модели:
ContentType. get_object_for_this_type ( ** kwargs ) ¶
Принимает набор допустимых аргументов поиска для модели, которую ContentType представляет, и выполняет для этой модели, возвращая соответствующий объект. a get() lookup
Возвращает класс модели, представленный этим ContentType экземпляром.
Например, мы могли бы посмотреть вверх ContentType для User модели:
А затем используйте его для запроса конкретного User или для получения доступа к User классу модели:
Вместе get_object_for_this_type() и model_class() позволяют реализовать два чрезвычайно важных варианта использования:
Некоторые из приложений, входящих в пакет Django, используют последний метод. Например, в платформе аутентификации Django используется модель с внешним ключом для ; это позволяет представить такие понятия, как «можно добавить запись в блог» или «можно удалить новость». the permissions system Permission ContentType Permission
ContentTypeManager ¶
Очищает внутренний кеш, используемый ContentType для отслеживания моделей, для которых были созданы ContentType экземпляры. Вам, вероятно, никогда не понадобится вызывать этот метод самостоятельно; Django будет вызывать его автоматически, когда это необходимо.
Принимает либо класс модели, либо экземпляр модели и возвращает ContentType экземпляр, представляющий эту модель. for_concrete_model=False позволяет ContentType получить прокси-модель.
Принимает переменное количество классов модели и возвращает словарь, сопоставляющий классы модели с ContentType экземплярами, представляющими их. for_concrete_models=False позволяет получать ContentType прокси-модели.
Этот get_for_model() метод особенно полезен, когда вы знаете, что вам нужно работать с a, ContentType но не хотите тратить время на получение метаданных модели для выполнения поиска вручную:
Родовые отношения ¶
Добавление внешнего ключа из одной из ваших собственных моделей, чтобы ContentType позволить вашей модели эффективно привязать себя к другому классу модели, как в примере Permission модели выше. Но можно пойти еще дальше и использовать ContentType для включения действительно общих (иногда называемых «полиморфными») отношений между моделями.
Например, его можно использовать для такой системы тегов:
Обычный ForeignKey может «указывать» только на одну другую модель, что означает, что если бы TaggedItem модель использовала a, ForeignKey ей пришлось бы выбрать одну и только одну модель для хранения тегов. Приложение contenttypes предоставляет специальный тип поля ( GenericForeignKey ), который позволяет обойти это и позволяет устанавливать отношения с любой моделью:
Настройка состоит из трех частей GenericForeignKey :
Совместимость типов первичного ключа
Поле «object_id» не обязательно должно быть того же типа, что и поля первичного ключа в связанных моделях, но их значения первичного ключа должны приводиться к тому же типу, что и поле «object_id» по его get_db_prep_value() методу.
Для максимальной гибкости вы можете использовать, для TextField которого не определена максимальная длина, однако это может привести к значительным потерям производительности в зависимости от вашей базы данных.
Не существует универсального решения для выбора наилучшего типа поля. Вы должны оценить модели, на которые вы предполагаете указывать, и определить, какое решение будет наиболее эффективным для вашего варианта использования.
Сериализация ссылок на ContentType объекты
Это позволит использовать API, аналогичный тому, который используется для обычного ForeignKey ; у каждого TaggedItem будет content_object поле, которое возвращает объект, с которым он связан, и вы также можете назначить это поле или использовать его при создании TaggedItem :
Если соответствующий объект удаляется, то content_type и object_id поля остаются установленными в их исходные значения и GenericForeignKey возвращает None :
Точно так же GenericForeignKey s не появляется в ModelForm s.
Обратные отношения общего положения ¶
Связь связанного объекта с этим объектом по умолчанию не существует. Настройка related_query_name создает отношение от связанного объекта к этому. Это позволяет запрашивать и фильтровать связанный объект.
Если вы знаете, какие модели вы будете использовать чаще всего, вы также можете добавить «обратную» общую связь, чтобы включить дополнительный API. Например:
Bookmark у каждого экземпляра будет tags атрибут, который можно использовать для получения связанных с ними TaggedItems :
remove() Вызов будет навалом удалить указанные объекты модели:
Этот clear() метод можно использовать для массового удаления всех связанных объектов для экземпляра:
Определение GenericRelation с помощью related_query_name set позволяет запрашивать из связанного объекта:
Это позволяет выполнять фильтрацию, упорядочивание и другие операции запросов на Bookmark from TaggedItem :
Родовые отношения и агрегирование ¶
Родовое отношение в формах ¶
absolute_max И can_delete_extra были добавлены аргументы.
Общие отношения в админке ¶
GenericInlineModelAdmin Класс наследует все свойства от InlineModelAdmin класса. Однако он добавляет пару собственных для работы с родовым отношением:
класс GenericTabularInline ¶ класс GenericStackedInline ¶
Подклассы GenericInlineModelAdmin с составными и табличными макетами соответственно.
Documentation
The contenttypes framework¶
Django includes a contenttypes application that can track all of the models installed in your Django-powered project, providing a high-level, generic interface for working with your models.
Overview¶
Instances of ContentType have methods for returning the model classes they represent and for querying objects from those models. ContentType also has a custom manager that adds methods for working with ContentType and for obtaining instances of ContentType for a particular model.
Relations between your models and ContentType can also be used to enable “generic” relationships between an instance of one of your models and instances of any model you have installed.
Installing the contenttypes framework¶
It’s generally a good idea to have the contenttypes framework installed; several of Django’s other bundled applications require it:
The ContentType model¶
Each instance of ContentType has two fields which, taken together, uniquely describe an installed model:
The name of the model class.
Additionally, the following property is available:
The human-readable name of the content type. This is taken from the verbose_name attribute of the model.
Let’s look at an example to see how this works. If you already have the contenttypes application installed, and then add the sites application to your INSTALLED_APPS setting and run manage.py migrate to install it, the model django.contrib.sites.models.Site will be installed into your database. Along with it a new instance of ContentType will be created with the following values:
Methods on ContentType instances¶
Each ContentType instance has methods that allow you to get from a ContentType instance to the model it represents, or to retrieve objects from that model:
ContentType. get_object_for_this_type (**kwargs)¶
Takes a set of valid lookup arguments for the model the ContentType represents, and does a get() lookup on that model, returning the corresponding object.
Returns the model class represented by this ContentType instance.
For example, we could look up the ContentType for the User model:
Together, get_object_for_this_type() and model_class() enable two extremely important use cases:
Several of Django’s bundled applications make use of the latter technique. For example, the permissions system in Django’s authentication framework uses a Permission model with a foreign key to ContentType ; this lets Permission represent concepts like “can add blog entry” or “can delete news story”.
The ContentTypeManager ¶
Clears an internal cache used by ContentType to keep track of models for which it has created ContentType instances. You probably won’t ever need to call this method yourself; Django will call it automatically when it’s needed.
get_for_model (model, for_concrete_model=True)¶
Takes either a model class or an instance of a model, and returns the ContentType instance representing that model. for_concrete_model=False allows fetching the ContentType of a proxy model.
get_for_models (*models, for_concrete_models=True)¶
Takes a variadic number of model classes, and returns a dictionary mapping the model classes to the ContentType instances representing them. for_concrete_models=False allows fetching the ContentType of proxy models.
get_by_natural_key (app_label, model)¶
Returns the ContentType instance uniquely identified by the given application label and model name. The primary purpose of this method is to allow ContentType objects to be referenced via a natural key during deserialization.
The get_for_model() method is especially useful when you know you need to work with a ContentType but don’t want to go to the trouble of obtaining the model’s metadata to perform a manual lookup:
Generic relations¶
Adding a foreign key from one of your own models to ContentType allows your model to effectively tie itself to another model class, as in the example of the Permission model above. But it’s possible to go one step further and use ContentType to enable truly generic (sometimes called “polymorphic”) relationships between models.
For example, it could be used for a tagging system like so:
A normal ForeignKey can only “point to” one other model, which means that if the TaggedItem model used a ForeignKey it would have to choose one and only one model to store tags for. The contenttypes application provides a special field type ( GenericForeignKey ) which works around this and allows the relationship to be with any model:
There are three parts to setting up a GenericForeignKey :
Primary key type compatibility
The “object_id” field doesn’t have to be the same type as the primary key fields on the related models, but their primary key values must be coercible to the same type as the “object_id” field by its get_db_prep_value() method.
For maximum flexibility you can use a TextField which doesn’t have a maximum length defined, however this may incur significant performance penalties depending on your database backend.
There is no one-size-fits-all solution for which field type is best. You should evaluate the models you expect to be pointing to and determine which solution will be most effective for your use case.
Serializing references to ContentType objects
This will enable an API similar to the one used for a normal ForeignKey ; each TaggedItem will have a content_object field that returns the object it’s related to, and you can also assign to that field or use it when creating a TaggedItem :
If the related object is deleted, the content_type and object_id fields remain set to their original values and the GenericForeignKey returns None :
Likewise, GenericForeignKey s does not appear in ModelForm s.
Reverse generic relations¶
The relation on the related object back to this object doesn’t exist by default. Setting related_query_name creates a relation from the related object back to this one. This allows querying and filtering from the related object.
If you know which models you’ll be using most often, you can also add a “reverse” generic relationship to enable an additional API. For example:
Bookmark instances will each have a tags attribute, which can be used to retrieve their associated TaggedItems :
The remove() call will bulk delete the specified model objects:
The clear() method can be used to bulk delete all related objects for an instance:
Defining GenericRelation with related_query_name set allows querying from the related object:
This enables filtering, ordering, and other query operations on Bookmark from TaggedItem :
Just as GenericForeignKey accepts the names of the content-type and object-ID fields as arguments, so too does GenericRelation ; if the model which has the generic foreign key is using non-default names for those fields, you must pass the names of the fields when setting up a GenericRelation to it. For example, if the TaggedItem model referred to above used fields named content_type_fk and object_primary_key to create its generic foreign key, then a GenericRelation back to it would need to be defined like so:
Generic relations and aggregation¶
Generic relation in forms¶
The absolute_max and can_delete_extra arguments were added.
Generic relations in admin¶
These classes and functions enable the use of generic relations in forms and the admin. See the model formset and admin documentation for more information.
The GenericInlineModelAdmin class inherits all properties from an InlineModelAdmin class. However, it adds a couple of its own for working with the generic relation:
class GenericTabularInline ¶ class GenericStackedInline ¶
Subclasses of GenericInlineModelAdmin with stacked and tabular layouts, respectively.
документация Django 3.0
Обзор¶
Взаимосвязь между ContentType и вашими моделями можно использовать для создания «обобщенных» («generic» ) отношений между экземпляром вашей модели и экземпляром любой другой модели в проекте.
Установка и подключение contenttypes¶
Рекомендуется всегда подключать фреймворк контентных типов в проект, поскольку его наличие требуется для работы ряда других встроенных приложений Django:
Модель ContentType ¶
Каждый экземпляр ContentType содержит два поля, которые вместе уникальным образом описывают каждую модель в приложении:
Имя приложения в которое входит данная модель. Данные берутся из атрибута app_label модели и включают в себя только последнюю часть пути, который используется для импорта модели. Н-р, в случае «django.contrib.contenttypes» используется значение атрибута app_label для «contenttypes».
Также доступны следующие свойства:
«Читабельное» имя модели. Берется из атрибута verbose_name модели.
Методы экземпляра ContentType ¶
ContentType. get_object_for_this_type ( ** kwargs )¶
Принимает набор корректных аргументов запроса для модели, представленной данным ContentType и выполняет метод get() этой модели, возвращая соответствующий объект.
Н-р, мы можем получить экземпляр ContentType для модели User следующим образом:
ContentTypeManager ¶
Обобщенные связи(generic relations)¶
Например, так можно реализовать систему тегов:
Существуют три правила по созданию и настройке GenericForeignKey :
Тип первичного ключа
Не существует универсального решения для выбора наилучшего типа поля. Вы должны изучить модели с которыми собираетесь работать, и на основании этого принять решение о выборе типа для поля, руководствуясь принципами эффективности.
Сериализация связей с ContentType
Если связанный объект удален, поля content_type и object_id получат начальные значения и GenericForeignKey вернет None :
Также GenericForeignKey s не отображется в ModelForm s.
Обратная обобщенная связь(reverse generic relations)¶
По умолчанию обратная связь не создается. Чтобы создать такую связь, укажите параметр related_query_name поля. Это позволять получить связанные объекты и использовать поле для фильтрации результатов запроса.
Если модель, с которой предстоит работать наиболее часто, известна заранее, вы можете добавить «обратную» обобщенную связь между моделями и использовать дополнительные возможности API. Н-р:
Это позволяет фильтровать, сортировать и выполнять запросы по Bookmark из TaggedItem :
Обобщенные связи и агрегация¶
Обобщенные связи в формах¶
Обобщенные связи в админке¶
class GenericTabularInline ¶ class GenericStackedInline ¶
Подклассы GenericInlineModelAdmin позволяющие настраивать отображение данных в сложенном(stacked) или табличном(tabular) виде, соответственно.
Документация Django 1.9
Обзор¶
Взаимосвязь между ContentType и вашими моделями можно использовать для создания “обобщенных” (“generic” ) отношений между экземпляром вашей модели и экземпляром любой другой модели в проекте.
Установка и подключение contenttypes¶
Рекомендуется всегда подключать contenttypes фреймворк в проекте, поскольку его наличие требуется для работы ряда других встроенных приложений Django.
Встроенное приложение администрирования Django использует contenttypes для ведения логов по добавлению или изменению объектов через админку.
Модель ContentType ¶
Каждый экземпляр ContentType содержит два поля, которые вместе уникальным образом описывают каждую модель в приложении:
Первое, это имя приложения в которое входит данная модель. Данные берутся из атрибута app_label модели и включают в себя только последнюю часть пути, который используется для импорта модели. Н-р, в случае “django.contrib.contenttypes” используется значение атрибута app_label для “contenttypes”.
Также доступны следующие свойства:
“Читабельное” имя модели. Берется из атрибута verbose_name модели.
Атрибут app_label со значением ‘sites’ (последняя часть the last part of the Python path “django.contrib.sites”).
Методы экземпляра ContentType ¶
ContentType. get_object_for_this_type (**kwargs)¶
Принимает набор корректных фильтров полей(lookup arguments) для модели, представленной данным ContentType и выполняет метод get() этой модели, возвращая соответствующий объект.
Н-р, мы можем получить экземпляр ContentType для модели User следующим образом:
Вы можете использовать ContentType чтобы связать экземпляр вашей модели с любыми произвольными классами моделей проекта, и использовать указанные методы для доступа к этим моделям.
The ContentTypeManager ¶
get_for_model (model, for_concrete_model=True)¶
get_for_models (*models, for_concrete_models=True)¶
get_by_natural_key (app_label, model)¶
Обобщенные связи(generic relations)¶
Вот простой пример: реализуем систему тэгов(ярлычков), которая могла бы выглядеть так
Существуют три правила по созданию и настройке GenericForeignKey :
Тип первичного ключа
Не существует универсального решения для выбора наилучшего типа поля. Вы должны изучить модели с которыми собираетесь работать, и на основании этого принять решение о выборе типа для поля, руководствуясь принципами эффективности.
Сериализация связей с ContentType
Также GenericForeignKey s не отображется в ModelForm s.
Обратная обобщенная связь(reverse generic relations)¶
По умолчанию обратная связь не создается. Чтобы создать такую связь, укажите параметр related_query_name поля. Это позволять получить связанные объекты и использовать поле для фильтрации результатов запроса.
Если модель, с которой предстоит работать наиболее часто, известна заранее, вы можете добавить “обратную” обобщенную связь между моделями и использовать дополнительные возможности API. Н-р:
Это позволяет фильтровать, сортировать и выполнять запросы по Bookmark из TaggedItem :
Ну и конечно, если вы не захотите добавить обратную связь, вы можете получить доступ к объекту и “обходным путем”:
Обратите внимание, если в модели с GenericRelation не используются значения по умолчанию для ct_field или fk_field для GenericForeignKey (например, у вас есть модель Comment с ct_field=»object_pk» ), вам необходимо установить content_type_field и/или object_id_field таким образом, чтобы значения ct_field и fk_field в GenericRelation соответствовали значениям для ct_field и fk_field в модели содержащей GenericForeignKey :
Обобщенные связи и агрегация¶
Обобщенные связи в формах¶
class BaseGenericInlineFormSet ¶ generic_inlineformset_factory (model, form=ModelForm, formset=BaseGenericInlineFormSet, ct_field=»content_type», fk_field=»object_id», fields=None, exclude=None, extra=3, can_order=False, can_delete=True, max_num=None, formfield_callback=None, validate_max=False, for_concrete_model=True, min_num=None, validate_min=False)¶
Обобщенные связи в админке¶
class GenericTabularInline ¶ class GenericStackedInline ¶
Подклассы GenericInlineModelAdmin позволяющие настраивать отображение данных в сложенном(stacked) или табличном(tabular) виде, соответственно.