django contains без учета регистра

Нечувствительные к регистру уникальные поля модели в Django?

У меня в основном имя пользователя уникально (без учета регистра), но регистр имеет значение при отображении, как указано пользователем.

У меня следующие требования:

Возможно ли это в Django?

Единственное решение, которое я придумал, это «как-то» переопределить менеджер моделей, использовать дополнительное поле или всегда использовать «iexact» в поиске.

Я на Django 1.3 и PostgreSQL 8.4.2.

7 ответов

Если вы попытаетесь INSERT смешать имя, которое уже есть в нижнем регистре, вы получите уникальную ошибку нарушения ключа.
Для быстрого поиска равенства используйте запрос, подобный этому:

Используйте то же выражение, что и в индексе (чтобы планировщик запросов распознал совместимость), и это будет очень быстро.

Вы можете использовать lookup = ‘iexact’ в UniqueValidator на сериализаторе, например так: Уникальное поле модели в Django и чувствительность к регистру (postgres )

При переопределении менеджера моделей у вас есть два варианта. Сначала нужно просто создать новый метод поиска:

Вместо этого вы можете использовать тип citext postgres и больше не беспокоиться о каком-либо iexact. Просто отметьте в модели, что поле не учитывает регистр. Гораздо проще решение.

Поскольку имя пользователя всегда в нижнем регистре, рекомендуется использовать настраиваемое поле модели нижнего регистра в Django. Для простоты доступа и аккуратности кода создайте новый файл fields.py в папке своего приложения.

Использование в models.py

Вы также можете переопределить «get_prep_value» с помощью поля моделей Django

Источник

Запросы ¶

В этом руководстве (и в справочнике) мы будем ссылаться на следующие модели, составляющие приложение веб-журнала:

Создание объектов ¶

Для представления данных таблицы базы данных в объектах Python Django использует интуитивно понятную систему: класс модели представляет таблицу базы данных, а экземпляр этого класса представляет конкретную запись в таблице базы данных.

Чтобы создать объект, создайте его экземпляр, используя аргументы ключевого слова для класса модели, а затем вызовите, save() чтобы сохранить его в базе данных.

save() Метод не имеет возвращаемого значения.

save() использует ряд дополнительных параметров, не описанных здесь. См. Документацию для save() получения полной информации.

Чтобы создать и сохранить объект за один шаг, используйте create() метод.

Сохранение изменений в объектах ¶

Сохранение ForeignKey и ManyToManyField поля ¶

Django пожалуется, если вы попытаетесь назначить или добавить объект неправильного типа.

Получение объектов ¶

Для извлечения объектов из базы данных, построить с QuerySet помощью Manager на вашу модель класса.

Managers доступны только через классы модели, а не из экземпляров модели, чтобы обеспечить разделение между операциями «уровня таблицы» и операциями «уровня записи».

Получение всех объектов ¶

all() Метод возвращает QuerySet все объекты в базе данных.

Получение определенных объектов с помощью фильтров ¶

QuerySet Возвращаемый all() описывает все объекты в таблице базы данных. Однако обычно вам нужно выбрать только подмножество полного набора объектов.

filter(**kwargs) Возвращает новые QuerySet содержащие объекты, соответствующие заданным параметрам поиска. exclude(**kwargs) Возвращает новые QuerySet содержащие объекты, которые не соответствуют заданным параметрам поиска.

Параметры поиска ( **kwargs в определениях функций выше) должны быть в формате, описанном в разделе «Поиск полей» ниже.

Например, чтобы получить список QuerySet записей в блоге за 2006 год, используйте следующее filter() :

С классом менеджера по умолчанию он такой же, как:

Объединение фильтров ¶

Отфильтрованные QuerySet s уникальны ¶

QuerySet ленивы ¶

Получение одного объекта с помощью get() ¶

Если вы знаете, что существует только один объект, соответствующий вашему запросу, вы можете использовать get() метод, Manager который возвращает объект напрямую:

Другие QuerySet методы ¶

Ограничение QuerySet s ¶

Например, это возвращает первые 5 объектов ( ): LIMIT 5

Это возвращает объекты с шестого по десятый ( ): OFFSET 5 LIMIT 5

Отрицательная индексация (т.е. Entry.objects.all()[-1] ) не поддерживается.

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

Чтобы получить отдельный объект, а не список (например ), используйте индекс вместо фрагмента. Например, после упорядочивания записей в алфавитном порядке по заголовкам возвращается первая запись в базе данных: SELECT foo FROM bar LIMIT 1 Entry

Это примерно эквивалентно:

Обратите внимание, однако, что первый из них будет повышаться, IndexError а второй будет повышаться, DoesNotExist если ни один объект не соответствует заданным критериям. Подробнее get() см.

Поиск полей ¶

переводится (примерно) в следующий SQL:

Python имеет возможность определять функции, которые принимают произвольные аргументы значения имени, имена и значения которых оцениваются во время выполнения. Дополнительные сведения см. В разделе « Аргументы ключевых слов» в официальном руководстве по Python.

«Точное» совпадение. Например:

Сгенерирует SQL в следующих строках:

Например, следующие два оператора эквивалентны:

Соответствие без учета регистра. Итак, запрос:

Тест на сдерживание с учетом регистра. Например:

Примерно переводится на этот SQL:

Поиск, охватывающий отношения ¶

Django предлагает мощный и интуитивно понятный способ «следить» за отношениями при поиске, JOIN автоматически заботясь о SQL за кулисами. Чтобы охватить взаимосвязь, используйте имя поля связанных полей в моделях, разделенное двойным подчеркиванием, пока не дойдете до нужного поля.

В этом примере извлекаются все Entry объекты с Blog которого name является : ‘Beatles Blog’

Этот охват может быть сколь угодно глубоким.

Он работает и в обратном направлении. При этом по умолчанию вы ссылаетесь на «обратную» связь при поиске, используя имя модели в нижнем регистре. can be customized

Если вы выполняете фильтрацию по нескольким отношениям, и одна из промежуточных моделей не имеет значения, которое соответствует условию фильтрации, Django будет рассматривать ее, как если бы там был пустой (все значения NULL ), но действительный объект. Все это означает, что никаких ошибок возникать не будет. Например, в этом фильтре:

Составные многозначные отношения ¶

Чтобы справиться с обеими этими ситуациями, Django имеет последовательный способ обработки filter() вызовов. Все внутри одного filter() вызова применяется одновременно, чтобы отфильтровать элементы, соответствующие всем этим требованиям. Последовательные filter() вызовы дополнительно ограничивают набор объектов, но для многозначных отношений они применяются к любому объекту, связанному с первичной моделью, не обязательно к тем объектам, которые были выбраны предыдущим filter() вызовом.

Это может показаться немного запутанным, поэтому, надеюсь, прояснит ситуацию. Чтобы выбрать все блоги, которые содержат записи как со словом «Lennon» в заголовке, так и опубликованные в 2008 году (одна и та же запись удовлетворяет обоим условиям), мы должны написать:

Чтобы выбрать все блоги, которые содержат запись со словом «Леннон» в заголовке, а также запись, опубликованную в 2008 году, мы должны написать:

Например, следующий запрос исключает блоги, содержащие как записи со словом «Леннон» в заголовке, так и записи, опубликованные в 2008 году:

Фильтры могут ссылаться на поля в модели ¶

В приведенных выше примерах мы построили фильтры, которые сравнивают значение поля модели с константой. Но что, если вы хотите сравнить значение поля модели с другим полем той же модели?

Django позволяет проводить такие сравнения. Экземпляры выступают в качестве ссылки на поле модели в запросе. Эти ссылки затем можно использовать в фильтрах запросов для сравнения значений двух разных полей в одном экземпляре модели. F expressions F()

Например, чтобы найти список всех записей блога, в которых было больше комментариев, чем пингбэков, мы создаем F() объект для ссылки на счетчик пингбэков и используем этот F() объект в запросе:

Django поддерживает использование сложения, вычитания, умножения, деления, по модулю и степенной арифметики с F() объектами, как с константами, так и с другими F() объектами. Чтобы найти все записи блога с более чем вдвое большим количеством комментариев, чем пингбэков, мы модифицируем запрос:

Чтобы найти все записи, в которых рейтинг записи меньше суммы количества ответов и комментариев, мы должны выполнить запрос:

Для полей даты и даты / времени вы можете добавить или вычесть timedelta объект. Следующее будет возвращать все записи, которые были изменены более чем через 3 дня после их публикации:

Oracle не поддерживает побитовую операцию XOR.

Выражения могут ссылаться на преобразования ¶

Django поддерживает использование преобразований в выражениях.

Например, чтобы найти все Entry объекты, опубликованные в том же году, когда они были в последний раз изменены:

Чтобы найти самый ранний год публикации записи, мы можем выполнить запрос:

В этом примере определяется значение записи с наивысшим рейтингом и общее количество комментариев ко всем записям за каждый год:

pk Поиска ярлык ¶

Для удобства Django предоставляет pk ярлык для поиска, который расшифровывается как «первичный ключ».

В примере Blog модели первичным ключом является id поле, поэтому эти три оператора эквивалентны:

pk поиск также работает по объединениям. Например, эти три утверждения эквивалентны:

Использование знаков процента и подчеркивания в LIKE операторах ¶

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

Django позаботится о цитировании за вас; итоговый SQL будет выглядеть примерно так:

То же самое и с подчеркиванием. Знаки процента и подчеркивания обрабатываются для вас прозрачно.

Кэширование и QuerySet s ¶

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

Помните об этом поведении кеширования, потому что оно может вас укусить, если вы не будете QuerySet правильно использовать свои s. Например, следующее создаст две QuerySet s, оценит их и выбросит:

Это означает, что один и тот же запрос к базе данных будет выполнен дважды, что фактически удвоит нагрузку на вашу базу данных. Кроме того, существует вероятность, что два списка могут не включать одни и те же записи базы данных, потому что Entry они могли быть добавлены или удалены за долю секунды между двумя запросами.

Чтобы избежать этой проблемы, сохраните QuerySet и используйте его повторно:

Когда QuerySet s не кешируются ¶

Наборы запросов не всегда кэшируют свои результаты. При оценке только части набора запросов кеш проверяется, но если он не заполнен, то элементы, возвращаемые последующим запросом, не кэшируются. В частности, это означает, что ограничение набора запросов с помощью среза массива или индекса не приведет к заполнению кеша.

Например, многократное получение определенного индекса в объекте набора запросов будет каждый раз запрашивать базу данных:

Однако, если весь набор запросов уже был оценен, вместо этого будет проверяться кеш:

Вот несколько примеров других действий, которые приведут к оценке всего набора запросов и, следовательно, заполнению кеша:

Простая печать набора запросов не приведет к заполнению кеша. Это связано с тем, что вызов __repr__() возвращает только часть всего набора запросов.

Запрос JSONField ¶

Реализация поиска отличается, в JSONField основном, из-за наличия ключевых преобразований. Для демонстрации мы будем использовать следующий пример модели:

Хранение и запрос None ¶

Преобразование ключа, индекса и пути ¶

Чтобы запросить на основе заданного ключа словаря, используйте этот ключ в качестве имени поиска:

Несколько ключей можно объединить в цепочку для поиска пути:

Если ключ является целым числом, он будет интерпретирован как преобразование индекса в массиве:

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

Чтобы запросить отсутствующие ключи, используйте isnull поиск:

Из-за того, как работают запросы ключевого пути, exclude() и filter() не гарантируется создание исчерпывающих наборов. Если вы хотите включить объекты, у которых нет пути, добавьте isnull поиск.

Поскольку любая строка может быть ключом в объекте JSON, любой поиск, кроме перечисленных ниже, будет интерпретироваться как поиск ключа. Ошибок не возникает. Будьте особенно осторожны с ошибками при вводе и всегда проверяйте, работают ли ваши запросы так, как вы предполагаете.

Пользователи MariaDB и Oracle

Использование order_by() преобразований по ключу, индексу или пути отсортирует объекты, используя строковое представление значений. Это связано с тем, что MariaDB и Oracle Database не предоставляют функцию, которая преобразует значения JSON в их эквивалентные значения SQL.

Сдерживание и поиск ключей ¶

contains ¶

contains не поддерживается в Oracle и SQLite.

contained_by ¶

contained_by не поддерживается в Oracle и SQLite.

has_key ¶

Возвращает объекты, в которых данный ключ находится на верхнем уровне данных. Например:

has_keys ¶

Возвращает объекты, в которых все заданные ключи находятся на верхнем уровне данных. Например:

has_any_keys ¶

Возвращает объекты, в которых любой из заданных ключей находится на верхнем уровне данных. Например:

Сложные поиски с Q объектами ¶

Например, этот Q объект инкапсулирует один LIKE запрос:

Q Объекты могут быть объединены с использованием & и | операторов. Когда оператор используется для двух Q объектов, он дает новый Q объект.

Например, этот оператор дает один Q объект, который представляет собой «ИЛИ» двух «question__startswith» запросов:

Это эквивалентно следующему WHERE предложению SQL :

Вы можете составить заявления произвольной сложности путем объединения Q объектов с & и | операторами и использование вводной группировкой. Кроме того, Q объекты могут быть инвертированы с помощью

оператора, что позволяет выполнять комбинированный поиск, который объединяет как обычный запрос, так и запрос negated ( NOT ):

… Примерно переводится на SQL:

Функции поиска могут смешивать использование Q объектов и аргументов ключевого слова. Все аргументы, предоставленные функции поиска (будь то аргументы ключевого слова или Q объекты), объединяются «И» вместе. Однако, если Q объект предоставлен, он должен предшествовать определению любых аргументов ключевого слова. Например:

… Был бы допустимым запросом, эквивалентным предыдущему примеру; но:

… Не будет действительным.

Сравнение объектов ¶

Используя Entry приведенный выше пример, следующие два оператора эквивалентны:

Удаление объектов ¶

Например, это удаляет все Entry объекты с pub_date 2005 годом:

Обратите внимание, что delete() это единственный QuerySet метод, который не отображается в Manager самом файле. Это защитный механизм, предотвращающий случайный запрос Entry.objects.delete() и удаление всех записей. Если вы действительно хотите удалить все объекты, вам необходимо явно запросить полный набор запросов:

Копирование экземпляров модели ¶

Все усложняется, если вы используете наследование. Рассмотрим подкласс Blog :

Для a OneToOneField необходимо продублировать связанный объект и назначить его полю нового объекта, чтобы не нарушать однозначное ограничение уникальности. Например, предположение, что entry уже дублировано, как указано выше:

Одновременное обновление нескольких объектов ¶

С ForeignKey помощью этого метода можно установить только поля и поля, не связанные с отношениями. Чтобы обновить поле, не связанное с отношением, укажите новое значение как константу. Чтобы обновить ForeignKey поля, установите новое значение как новый экземпляр модели, на который вы хотите указать. Например:

Имейте в виду, что update() метод преобразуется непосредственно в инструкцию SQL. Это массовая операция для прямых обновлений. Он не запускает какие-либо save() методы в ваших моделях, не генерирует сигналы pre_save или post_save (которые являются следствием вызова save() ) и не учитывает параметр auto_now поля. Если вы хотите сохранить каждый элемент в a QuerySet и убедиться, что save() метод вызывается для каждого экземпляра, вам не нужна какая-либо специальная функция для его обработки. Перебери их и позвони save() :

Вызовы update также можно использовать для обновления одного поля на основе значения другого поля в модели. Это особенно полезно для увеличения счетчиков в зависимости от их текущего значения. Например, чтобы увеличить счетчик ответов для каждой записи в блоге: F expressions

Связанные объекты ¶

Отношения один-ко-многим ¶

Нападающий ¶

Если ForeignKey поле null=True установлено (т. Е. Допускает NULL значения), вы можете назначить None для удаления отношения. Пример:

Прямой доступ к отношениям «один ко многим» кэшируется при первом обращении к связанному объекту. Последующие обращения к внешнему ключу того же экземпляра объекта кэшируются. Пример:

Обратите внимание, что метод рекурсивно предварительно заполняет кеш всех отношений «один ко многим» заранее. Пример: select_related() QuerySet

Следуя отношениям «в обратном направлении» ¶

Использование кастомного реверсивного менеджера ¶

По умолчанию, RelatedManager используемый для обратных отношений является подклассом менеджера по умолчанию для этой модели. Если вы хотите указать другого менеджера для данного запроса, вы можете использовать следующий синтаксис:

Указание настраиваемого реверсивного менеджера также позволяет вызывать его настраиваемые методы:

Дополнительные методы для обработки связанных объектов ¶

Чтобы назначить члены связанного набора, используйте set() метод с итерацией экземпляров объекта. Например, если e1 и e2 являются Entry экземплярами:

Каждая «обратная» операция, описанная в этом разделе, немедленно влияет на базу данных. Каждое добавление, создание и удаление немедленно и автоматически сохраняется в базе данных.

Отношения многие-ко-многим ¶

Оба конца отношения «многие ко многим» получают автоматический доступ через API к другому концу. API работает аналогично «обратному» отношению «один ко многим», описанному выше.

Пример упрощает понимание:

Индивидуальные отношения ¶

Отношения «один к одному» очень похожи на отношения «многие к одному». Если вы определите в OneToOneField своей модели, экземпляры этой модели будут иметь доступ к связанному объекту через атрибут модели.

Разница заключается в «обратных» запросах. Связанная модель во взаимно-однозначном отношении также имеет доступ к Manager объекту, но Manager представляет отдельный объект, а не коллекцию объектов:

Если этой связи не назначен ни один объект, Django вызовет DoesNotExist исключение.

Экземпляры могут быть назначены обратной связи таким же образом, как вы назначаете прямую связь:

Как возможны обратные отношения? ¶

Другие объектно-реляционные преобразователи требуют, чтобы вы определяли отношения с обеих сторон. Разработчики Django считают, что это нарушение принципа DRY (Don’t Repeat Yourself), поэтому Django требует, чтобы вы определяли отношения только на одном конце.

Но как это возможно, учитывая, что класс модели не знает, какие другие классы модели связаны с ним, пока эти другие классы модели не будут загружены?

Запросы к связанным объектам ¶

Запросы, связанные со связанными объектами, подчиняются тем же правилам, что и запросы с обычными полями значений. При указании значения для запроса для сопоставления вы можете использовать либо сам экземпляр объекта, либо значение первичного ключа для объекта.

Возврат к необработанному SQL ¶

Источник

Работа с запросами¶

В этом руководстве (и в справочнике) мы будем ссылаться на следующие модели, которые составляют приложение Weblog:

Создание объектов¶

Для представления данных таблицы базы данных в объектах Python Django использует интуитивно понятную систему: класс модели представляет таблицу базы данных, а экземпляр этого класса представляет конкретную запись в таблице базы данных.

Предполагая, что модели находятся в файле mysite/blog/models.py :

Метод save() не имеет возвращаемого значения.

save() использует несколько дополнительных параметров, которые здесь не описаны. Смотрите документацию save() для получения полной информации.

Сохранение изменений в объектах¶

Сохранение полей ForeignKey и ManyToManyField ¶

Джанго сообщит, если вы попытаетесь назначить или добавить объект неправильного типа.

Получение объектов¶

Чтобы получить объекты из вашей базы данных, создайте QuerySet через Manager в своем классе модели.

Managers доступны только через классы модели, а не из экземпляров модели, чтобы обеспечить разделение между операциями на уровне таблицы и операциями на уровне записи.

Получение всех объектов¶

Метод all() возвращает QuerySet всех объектов в базе данных.

Получение определенных объектов с помощью фильтров¶

Например, чтобы получить QuerySet записей блога за 2006 год, используйте filter() примерно так:

С классом менеджера по умолчанию, он такой же, как:

Цепочки фильтров¶

Отфильтрованные QuerySet являются уникальными¶

Получение одного объекта с помощью get() ¶

Если вы знаете, что только один объект соответствует вашему запросу, вы можете использовать метод get() из Manager который возвращает объект напрямую:

Другие методы QuerySet ¶

Ограничение QuerySet ¶

Например, этот код возвращает первые 5 объектов ( LIMIT 5 ):

Это возвращает объекты с шестого по десятый ( OFFSET 5 LIMIT 5 ):

Отрицательное индексирование (т.е. Entry.objects.all()[-1] ) не поддерживается.

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

Чтобы извлечь один объект, а не список (например, SELECT foo FROM bar LIMIT 1 ), используйте простой индекс вместо среза. Например, этот код возвращает первый Entry в базе данных, после упорядочивания записей в алфавитном порядке по заголовку:

Это примерно эквивалентно:

Поиск по полям¶

переводит (примерно) в следующий SQL:

Python имеет возможность определять функции, которые принимают произвольные аргументы имя-значение, имена и значения которых оцениваются во время выполнения. Для получения дополнительной информации см. Keyword Arguments в официальном руководстве по Python.

«Точное» совпадение. Например:

Будет генерировать SQL по этим строкам:

Например, следующие два оператора эквивалентны:

Это сделано для удобства, потому что точный поиск является распространенным случаем.

Соответствие без учета регистра. Итак, запрос:

Проверка содержимого в зависимости от регистра. Например:

Примерно переводится в такой SQL:

Поиск, который использует отношения¶

Django предлагает мощный и интуитивно понятный способ «отслеживать» отношения в поисках, автоматически заботясь о SQL JOIN для вас, за кулисами. Чтобы охватить отношение, просто используйте имя поля связанных полей в моделях, разделенных двойным подчеркиванием, пока не дойдете до нужного поля.

Этот охват может быть настолько глубоким, насколько вы захотите.

Если вы фильтруете по нескольким отношениям и одна из промежуточных моделей не имеет значения, которое удовлетворяет условию фильтра, Django будет обрабатывать его как пустой (все значения NULL ), но допустимый объект там. Все это означает, что никакой ошибки не возникнет. Например, в этом фильтре:

Охватывающие многозначные отношения¶

Это может показаться немного запутанным, поэтому, надеемся, пример прояснит. Чтобы выбрать все блоги, которые содержат записи с «Lennon» в заголовке и которые были опубликованы в 2008 году (та же запись, удовлетворяющая обоим условиям), мы должны написать:

Чтобы выбрать все блоги, которые содержат запись с «Lennon» в заголовке, а также запись, которая была опубликована в 2008 году, мы должны написать:

Предположим, что существует только один блог, в котором есть записи, содержащие «Lennon» и записи 2008 года, но ни одна из записей 2008 года не содержит «Lennon». Первый запрос не вернет ни одного блога, но второй запрос вернет этот блог.

Например, следующий запрос исключит блоги, содержащие обе записи с «Lennon» в заголовке и записи, опубликованные в 2008 году:

Фильтры могут ссылаться на поля модели¶

В приведенных выше примерах мы создали фильтры, которые сравнивают значение модельного поля с константой. Но что, если вы хотите сравнить значение поля модели с другим полем той же модели?

Например, чтобы найти список всех записей блога, у которых было больше комментариев, чем у пингбэков, мы создаем объект F() для ссылки на счетчик пингбэков и используем этот объект F() в запросе:

Чтобы найти все записи, в которых рейтинг записи меньше суммы пингбэков и комментариев, мы должны выполнить запрос:

Oracle не поддерживает побитовую операцию XOR.

Выражения могут ссылаться на преобразования¶

Django поддерживает использование преобразований в выражениях.

Чтобы найти самый ранний год публикации записи, мы можем выполнить запрос:

В этом примере определяется значение записи с наивысшим рейтингом и общее количество комментариев ко всем записям за каждый год:

Использование сокращения pk ¶

Поиск pk также работает через объединения. Например, эти три утверждения эквивалентны:

Экранирующие знаки процента и подчеркивания в выражениях LIKE ¶

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

Джанго заботится об экранировании для вас; результирующий SQL будет выглядеть примерно так:

То же самое касается подчеркивания. Оба знака процента и подчеркивания обрабатываются для вас прозрачно.

Кэширование и QuerySet ¶

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

Это означает, что один и тот же запрос к базе данных будет выполнен дважды, что фактически удваивает нагрузку на вашу базу данных. Кроме того, существует вероятность того, что два списка могут не включать в себя одни и те же записи базы данных, потому что «запись» может быть добавлена или удалена за доли секунды между двумя запросами.

Чтобы избежать этой проблемы, просто сохраните QuerySet и повторно используйте его:

Когда QuerySet не кэшируется¶

Queryset`ы не всегда кэшируют свои результаты. При оценке только части набора запросов проверяется кэш, но если он не заполняется, элементы, возвращаемые последующим запросом, не кэшируются. В частности, это означает, что ограничение набора запросов с использованием среза массива или индекса не заполнит кэш.

Например, многократное получение определенного индекса в объекте набора запросов будет каждый раз запрашивать базу данных:

Однако, если весь набор запросов уже был оценен, вместо этого будет проверяться кеш:

Вот несколько примеров других действий, которые приведут к оценке всего набора запросов и, следовательно, заполнению кеша:

Простой вывод набора запросов не заполнит кэш. Это связано с тем, что вызов __repr__() возвращает только часть всего набора запросов.

Запросы к JSONField ¶

Хранение и запрос для « None«¶

Преобразование ключа, индекса и пути¶

Для запроса на основе заданного ключа словаря используйте этот ключ в качестве имени поиска:

Несколько ключей могут быть объединены в цепочку для формирования пути поиска:

Если ключ является целым числом, он будет интерпретирован как преобразование индекса в массиве:

Чтобы запросить отсутствующие ключи, используйте поиск isnull :

Поскольку любая строка может быть ключом в объекте JSON, любой поиск, кроме перечисленных ниже, будет интерпретироваться как поиск ключа. Ошибок не возникает. Будьте особенно осторожны с опечатками и всегда проверяйте, работают ли ваши запросы так, как вы хотите.

Пользователи MariaDB и Oracle

Использование order_by() для преобразований ключа, индекса или пути отсортирует объекты с использованием строкового представления значений. Это связано с тем, что MariaDB и Oracle Database не предоставляют функцию, которая преобразует значения JSON в их эквивалентные значения SQL.

Сдерживание и ключевые поиски¶

contains ¶

contains не поддерживается в Oracle и SQLite.

contained_by ¶

contains_by не поддерживается в Oracle и SQLite.

has_key ¶

Возвращает объекты, в которых данный ключ находится на верхнем уровне данных. Например:

has_keys ¶

Возвращает объекты, в которых все данные ключи находятся на верхнем уровне данных. Например:

has_any_keys ¶

Возвращает объекты, где любой из указанных ключей находится на верхнем уровне данных. Например:

Сложные поиски с объектами Q ¶

Например, этот объект Q инкапсулирует один запрос LIKE :

Это эквивалентно следующему оператору SQL WHERE :

Вы можете составлять операторы произвольной сложности, комбинируя объекты Q с операторами & и | и используя группировку в скобках. Кроме того, объекты Q могут быть отменены с помощью оператора

, что позволяет комбинировать поиск, который объединяет как обычный запрос, так и отрицательный ( NOT ) запрос:

… примерно переводится в SQL как:

… будет правильным запросом, эквивалентным предыдущему примеру, но:

Сравнение объектов¶

Удаление объектов¶

Например, это удаляет все объекты Entry с pub_date 2005 года:

Копирование экземпляров модели¶

Все становится сложнее, если вы используете наследование. Рассмотрим подкласс Blog :

Для OneToOneField вы должны продублировать связанный объект и назначить его полю нового объекта, чтобы избежать нарушения однозначного уникального ограничения. Например, предполагая, что entry уже продублировано, как указано выше:

Обновление нескольких объектов одновременно¶

Метод update() применяется мгновенно и возвращает количество строк, соответствующих запросу (которое может быть не равно количеству обновленных строк, если некоторые строки уже имеют новое значение). Единственное ограничение на обновляемый QuerySet состоит в том, что он может получить доступ только к одной таблице базы данных: главной таблице модели. Вы можете фильтровать на основе связанных полей, но вы можете обновить только столбцы в основной таблице модели. Пример:

Вызовы обновлений также могут использовать выражения F для обновления одного поля на основе значения другого поля в модели. Это особенно полезно для увеличения счетчиков на основе их текущего значения. Например, чтобы увеличить количество пингбэков для каждой записи в блоге:

Связанные объекты¶

(За кулисами эта функциональность реализована с помощью дескрипторов Python. Это не должно иметь большого значения для вас, но мы отметим это здесь для любопытных.)

Отношения один ко многим¶

Прямые¶

Если поле ForeignKey установлено null=True (т.е. оно допускает значения NULL ), вы можете назначить None для удаления отношения. Пример:

Прямой доступ к отношениям «один ко многим» кэшируется при первом обращении к связанному объекту. Последующие обращения к внешнему ключу в том же экземпляре объекта кэшируются. Пример:

Обратные отношения¶

Использование собственного реверсивного менеджера¶

Указание собственного обратного менеджера также позволяет вам вызывать его пользовательские методы:

Дополнительные методы для обработки связанных объектов¶

Чтобы назначить членов связанного набора, используйте метод set() с повторяющимися экземплярами объекта. Например, если e1 и e2 являются экземпляром Entry :

Каждая «обратная» операция, описанная в этом разделе, оказывает непосредственное влияние на базу данных. Каждое добавление, создание и удаление немедленно и автоматически сохраняется в базе данных.

Отношения многие ко многим¶

Обе стороны отношения «многие ко многим» получают автоматический доступ API другой стороны. API работает аналогично «обратному» отношению «один ко многим» выше.

Пример облегчает понимание:

Отношения один-к-одному¶

Отношения один-к-одному очень похожи на отношения многие-к-одному. Если вы определяете OneToOneField в вашей модели, экземпляры этой модели будут иметь доступ к связанному объекту через простой атрибут модели.

Экземпляры могут быть назначены на обратную связь так же, как вы бы назначили прямую связь:

Как возможны обратные отношения?¶

Другие объектно-реляционные связи требуют, чтобы вы определяли отношения с обеих сторон. Разработчики Django считают, что это является нарушением принципа DRY (не повторяй себя), поэтому Django требует, чтобы вы определяли отношения только с одной стороны.

Но как это возможно, учитывая, что класс модели не знает, какие другие классы модели связаны с ним, пока эти другие классы модели не будут загружены?

Запросы к связанным объектам¶

Запросы, связанные со связанными объектами, подчиняются тем же правилам, что и запросы, включающие поля с обычными значениями. При указании значения для сопоставляемого запроса вы можете использовать либо сам экземпляр объекта, либо значение первичного ключа для объекта.

Откат к сырому SQL¶

Источник

Понравилась статья? Поделить с друзьями:
Добавить комментарий
  • Как сделать успешный бизнес на ритуальных услугах
  • Выездной кейтеринг в России
  • Риски бизнеса: без чего не обойтись на пути к успеху
  • dj holocost последнее право
  • diwali школьная форма официальный сайт