|
Оглавление
|
Знание о том, как можно создавать и изменять данные достаточно, но есть вероятность, что ваше приложение будет гораздо чаще обращаться к существующим объектам, чем создавать новые. Мы уже знаем способ получения каждой записи определённой модели: >>> Publisher.objects.all() [<Publisher: Apress>, <Publisher: O'Reilly>]
В общих чертах в SQL это выглядит так: SELECT
id, name, address, city, state_province, country, website
FROM book_publisher;
ЗамечаниеСледует отметить, что Django не использует SELECT * при просмотре данных, а вместо этого явно перечисляет все поля. Так было задумано изначально: в некоторых случаях использование SELECT * может повлиять на производительность, а главное, перечисление полей более соответствует нормам Искусства программирования на языке Python: «Явное лучше неявного». Для получения более подробной информации об Искусстве программирования на языке Python выполните в консоли Python команду import this.
Теперь внимательно рассмотрим строку Publisher.objects.all():
Любая выборка из базы данных работает по определённому шаблону — мы используем методы менеджера, который подключен к модели, по которой производится выборка.
Естественно, что достаточно редко требуется получать
весь набор данных из модели
единовременно. В большинстве случаев нам требуется обработать
небольшую часть данных. Мы можем осуществить это с помощью
метода >>> Publisher.objects.filter(name='Apress') [<Publisher: Apress>]
Метод SELECT id, name, address, city, state_province, country, website FROM books_publisher WHERE name = 'Apress';
Вы можете передать множество аргументов в
>>> Publisher.objects.filter(country="U.S.A.", state_province="CA") [<Publisher: Apress>]
Множество аргументов будут объединены с помощью SQL операторов AND. Пример станет таким: SELECT id, name, address, city, state_province, country, website FROM books_publisher WHERE country = 'U.S.A.' AND state_province = 'CA';
Следует отметить, что по умолчанию выборка использует SQL оператор = для точного совпадения. Также можно выполнять другие виды запросов: >>> Publisher.objects.filter(name__contains="press") [<Publisher: Apress>]
Обратите внимание на двойное подчёркивание между name и contains. Подобно Python это используется Django для выполнения «магических» действий. В данном случае __contains преобразовывается в SQL оператоh LIKE: SELECT id, name, address, city, state_province, country, website FROM books_publisher WHERE name LIKE '%press%';
Доступны множество типов выборок, включая icontains (независящий от регистра LIKE), startswith и endswith, а также range (SQL оператор BETWEEN). В приложении «Справочник по API взаимодействия с базой данных» подробно описаны все типы выборок.
Вышеприведённые примеры использования
>>> Publisher.objects.get(name="Apress") <Publisher: Apress>
Вместо списка (т.е., набора данных
>>> Publisher.objects.get(country="U.S.A.")
Traceback (most recent call last):
...
MultipleObjectsReturned: get() returned more than one Publisher --
it returned 2! Lookup parameters were {'country': 'U.S.A.'}
Запрос не возвращающий ни одного объекта тоже вызовет исключение: >>> Publisher.objects.get(name="Penguin")
Traceback (most recent call last):
...
DoesNotExist: Publisher matching query does not exist.
Исключение try:
p = Publisher.objects.get(name='Apress')
except Publisher.DoesNotExist:
print "Apress isn't in the database yet."
else:
print "Apress is in the database."
В процессе изучения предыдущих примеров вы могли заметить, что объекты возвращаются в случайном порядке. Раз мы не указали в каком порядке нам возвращать результат выборки, база данных отдаёт его в удобном для себя виде.
Очевидно, что для вашего приложения потребуется отсортировать
результат по какому-нибудь значению, скажем, по алфавиту. Для
этого использую метод >>> Publisher.objects.order_by("name")
[<Publisher: Apress>, <Publisher: O'Reilly>]
Это не сильно отличается от примера с методом
SELECT id, name, address, city, state_province, country, website FROM books_publisher ORDER BY name;
Мы можем производить сортировку по любому полю: >>> Publisher.objects.order_by("address")
[<Publisher: O'Reilly>, <Publisher: Apress>]
>>> Publisher.objects.order_by("state_province")
[<Publisher: Apress>, <Publisher: O'Reilly>]
Для выполнения сортировки по множеству полей (когда второе поле используется для сортировки элементов, у которых первое поле совпадает), используют множество аргументов: >>> Publisher.objects.order_by("state_province", "address")
[<Publisher: Apress>, <Publisher: O'Reilly>]
Также мы можем указать необходимость выполнять обратную сортировку с помощью префикса -(минус) для имени поля: >>> Publisher.objects.order_by("-name")
[<Publisher: O'Reilly>, <Publisher: Apress>]
Несмотря на все возможности, постоянное использование
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
def __unicode__(self):
return self.name
class Meta:
ordering = ["name"]
Здесь мы ввели новую концепцию: класс
Вы знаете как фильтровать данные и как их сортировать. Вы желаете узнать как это делать одновременно? Для этого следует «сцепить» операторы вместе: >>> Publisher.objects.filter(country="U.S.A.").order_by("-name")
[<Publisher: O'Reilly>, <Publisher: Apress>]
Как вы можете предполагать, в SQL представлении это будет выглядеть так: SELECT id, name, address, city, state_province, country, website FROM books_publisher WHERE country = 'U.S.A' ORDER BY name DESC;
Количество таких цепочек никак не ограничено[8]. Часто требуется получить только несколько строк результата выборки. Представьте, что в вашей базе находится несколько тысяч издателей, но вам надо отобразить только первого. Вы можете это осуществить с помощью возможностей стандартного списка Python: >>> Publisher.objects.order_by('name')[0]
<Publisher: Apress>
Это преобразуется в: SELECT id, name, address, city, state_province, country, website FROM books_publisher ORDER BY name LIMIT 1;
Аналогично, вы можете получать определённый набор данных с помощью стандартного синтаксиса языка Python для работы со списками: >>> Publisher.objects.order_by('name')[0:2]
Этот код вернёт два объекта и будет преобразован в: SELECT id, name, address, city, state_province, country, website FROM books_publisher ORDER BY name OFFSET 0 LIMIT 2;
Следует отметить, что отрицательные значения не поддерживаются: >>> Publisher.objects.order_by('name')[-1]
Traceback (most recent call last):
...
AssertionError: Negative indexing is not supported.
Но получить результат всё же возможно. Просто воспользуйтесь
методом >>> Publisher.objects.order_by('-name')[0]
Мы упоминали в разделе «Вставка и изменение данных» о том, что
метод
Например, нам требуется изменить в объекте
>>> p = Publisher.objects.get(name='Apress') >>> p.name = 'Apress Publishing' >>> p.save()
Это примерно преобразовывается в следующий SQL: SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE name = 'Apress';
UPDATE books_publisher SET
name = 'Apress Publishing',
address = '2855 Telegraph Ave.',
city = 'Berkeley',
state_province = 'CA',
country = 'U.S.A.',
website = 'http://www.apress.com'
WHERE id = 52;
(Следует отметить, что данный пример предполагает, что нужный нам объект имеет идентификатор 52.)
Вы можете видеть в данном примере, что метод
>>> Publisher.objects.filter(id=52).update(name='Apress Publishing')
SQL код будет более эффективным и не сможет вызвать «гонки»: UPDATE books_publisher SET name = 'Apress Publishing' WHERE id = 52;
Метод >>> Publisher.objects.all().update(country='USA') 2
Метод |
Увидели ошибку?
Выделите её мышкой и нажмите
-
Обработано:
1049
49
130
71
Версия книги
1.0
2.0
Версия 2.0 в процессе перевода!
Мой луч
Многообразие света
Полезное
Актуальные вакансии,
Python работа
для python-разработчиков.
Скачать в формате
CHM от 2 сентябряЗаказать PDF файл можно через почту, чат, джаббер. Всего 2WMZ. Содержимое точно соответствует содержимому сайта. Чем чаще заказываете — тем больше перевожу. Русская группа
Ускорить процесс перевода!
R130494980980
Z425285133788 E112528079659 U327380922061 Книга помогла реализовать:
|
| © 2008-2009 Ruslan Popov @ gmail.com | Powered by Django 1.1 beta 1 SVN-11114 |