LXF108:Django

Материал из Linuxformat.

(Различия между версиями)
Перейти к: навигация, поиск
(Финальные штрихи)
Строка 1: Строка 1:
-
{{Цикл/Django}}
+
Cycle {{/ Django}}
-
== Финальные штрихи ==
+
== == The final touches
-
: ''ЧАСТЬ 4 Уроки Django подходят к концу, наступает пора экзаменов – если не для вас, то для приложений уж точно. '''Никита Шультайс''' (http://shultais.ru) разберется с тестированием и пробежится по другим возможностям этого каркаса.''
+
:''PART 4 ​​Lessons Django comes to an end, there comes a time for exams - if not for you, for applications for sure. '''Nikita Shultays''' (http://shultais.ru) will deal with testing and go over other features of this framework.''
-
Новостная лента готова – но оправдает ли она ожидания
+
Newsline is ready - but whether it will meet expectations
-
пользователей? Ответ на этот вопрос может дать тестирование, лучше всего – в реальных условиях; но какие-то
+
users? The answer to this question can be tested, the best - in the real world, but some
-
основные вещи можно проверить еще на этапе разработки [http://www.thesiswritingservice.com/ thesis writers]. Если вы
+
basic things you can check at the stage of development [http://www.thesiswritingservice.com/ thesis writers]. If you
-
успели заглянуть в учебник [[LXF108:Rails|Rails]], то уже знаете о методологии TDD. Мы, однако, пойдем другим путем, и будем тестировать
+
time to look at the tutorial [[LXF108: Rails | Rails]], you already know about the methodology of TDD. However, we'll go the other way, and will test
-
приложение не до написания, а после.
+
application not to write, and after.
-
Дело это – серьезное и сложное, так как нам нужно учитывать
+
The point is - a serious and complex, as we need to consider
-
взаимодействие с БД, компиляцию шаблонов, обработку GET- и
+
interaction with the database, a compilation of templates, processes and GET-
-
POST-запросов и прочие компоненты системы: сбой в любом из
+
POST-requests and other system components: a failure in any of
-
них может вызвать нарушить работу всего сайта. К данной задаче
+
They can cause disrupt the entire site. Go to this problem
-
можно подойти с двух сторон:
+
can be approached from two sides:
-
* Тестирование в браузере. Речь идет о программах Twill (http://twill.idyll.org) и Selenium (http://selenium.openqa.org): они «запоминают» последовательность ваших действий для каждой страницы, а затем воспроизводят ее по запросу. Например, можно ввести в поля формы заведомо неверные данные, получить ожидаемую ошибку и повторять этот тест при каждом серьезном изменении в коде вашего приложения.
+
* Testing in your browser. We are talking about programs Twill (http://twill.idyll.org) and Selenium (http://selenium.openqa.org): they "remember" the sequence of your actions for each page, and then reproduce it on demand. For example, you can type in form fields obviously incorrect data, get the expected error and repeat the test whenever a major change in the code of your application.
-
* Тестирование на сервере. И тут Django не оставляет нас на произвол судьбы, предлагая сразу два варианта: doctest (тестирование через документацию) и unittest (модульное тестирование), плюс специальный клиент для отправки GET- и POST-запросов.
+
* Testing on the server. And then Django does not leave us to fend for themselves, offering just two options: doctest (tested via documentation) and unittest (unit testing), plus a special client to send a GET-and POST-requests.
-
Если вы давно программируете на Python, то вам, наверное,
+
If you've been programming in Python, then you probably
-
будет ближе doctest, а мигрантам из мира Java скорее придется по
+
will be closer doctest, and migrants from the Java world have more in
-
вкусу unittest. Никаких ограничений на их использование не накладывается: вы можете выбрать одну систему или применять обе сразу. Мы же остановимся на doctest.
+
taste unittest. There are no restrictions on their use is imposed: you can choose one system or use both at once. We also discuss the doctest.
-
=== Документируй это! ===
+
=== Document it! ===
-
Строка документации в Python – это обычный текст, размещаемый
+
Line documentation in Python - it is plain text that you place
-
после определения функции или класса непосредственно в исходном
+
after the definition of a function or class directly in the source
-
коде. Она же предоставляет содержимое для атрибута __doc__. Как
+
code. It also provides content for the attribute __doc__. As
-
правило, ее помещают в тройные кавычки ("""), что позволяет вводить
+
Typically, it is placed in triple quotes ("""), that allows you to enter
-
сложные конструкции с переносами строк, отступами, теми же кавычками и... тестами. Этим мы и воспользуемся.
+
complex structures with line breaks, indentation, the same quotes and ... tests. That's what we use.
-
Тесты могут находится в файлах моделей (models.py) – для проверки последних – и в специальных файлах tests.py, расположенных
+
Tests can be found in the model files (models.py) - to check the latest - and in special files tests.py, located
-
в директории приложения. К примеру, создайте файл news/tests.py
+
in the application directory. For example, create a news / tests.py
-
такого содержания:
+
to the following:
<source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
<source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
-
# -*- coding: utf-8 -*-
+
# -*- Coding: utf-8 -*-
-
"""
+
"" "
-
>>> from news.models import News
+
>>> From news.models import News
-
>>> from datetime import datetime
+
>>> From datetime import datetime
-
>>> news = News(title="Заголовок",description="Описание",pub_date=datetime.now(), text="Текст")
+
>>> News = News (title = "Title", description = "Description", pub_date = datetime.now (), text = "text")
-
>>> news.save()
+
>>> News.save ()
-
>>> news = News.objects.get(pk=1)
+
>>> News = News.objects.get (pk = 1)
-
>>> print news.title.encode('utf-8')
+
>>> Print news.title.encode ('utf-8')
-
Заголовок
+
 Title
-
"""
+
"" "
-
</source>
+
</ Source>
-
В строке 1 задается кодировка, а начиная с третьей идет сам
+
In line 1 encoding, but since the third is very
-
тест. Заметьте, что каждая строка начинается с трех знаков «больше» (>>>), как в интерактивном режиме работы Python. В строке 10
+
test. Note that each line begins with three characters "more" (>>>), in the interactive mode, Python. Line 10
-
этих знаков нет, так как она содержит ожидаемый вывод команды
+
These characters do not, because it contains the expected output
-
print со строки 9.
+
print from line 9.
-
[[Изображение:LXF108 85 1.png|thumb|200px|Рис. 1. Тест пройден удачно!]]
+
[[Image: LXF108 85 1.png | thumb | 200px | Fig. 1. Test passed successfully!]]
-
Перед тем, как запустить тест, в settings.py нужно добавить
+
Before running the test, you need to add in settings.py
-
строку
+
line
-
TEST_DATABASE_CHARSET="UTF8"
+
 TEST_DATABASE_CHARSET = "UTF8"
-
чтобы кодировки файла и базы данных совпадали. Перед выполнением теста Django создаст специальную вспомогательную БД, поэтому
+
to file encoding and the database match. Before performing the test, Django will create a special auxiliary databases, so
-
пользователь, указанный в settings.DATABASE_USER, должен иметь
+
the user specified in settings.DATABASE_USER, must have
-
соответствующие права. Для начала тестирования введите команду:
+
the appropriate authority. To begin testing, type:
-
python manage.py test news
+
 python manage.py test news
-
после выполнения которой вы увидите примерно то, что показано
+
after which you will see something that shows
-
на рис. 1.
+
Fig. 1.
-
Сообщения похожи на появляющиеся во время создания таблиц
+
Messages similar to appear during the creation of tables
-
при первой установке, но теперь все происходит в тестовой БД. В
+
when you first install, but now it happens in a test database. In
-
конце отображается число выполненных тестов, их результаты и
+
end shows the number of tests performed, their results and
-
уведомление об уничтожении тестовой базы. Мы проверяли наше
+
notified about the destruction of a test material. We checked our
-
приложение (news), но, как вы помните, Django содержит несколько
+
application (news), but, as you know, Django provides a few
-
собственных приложений и представлений (например, «админку»)
+
own applications and representations (eg, "admin") -
-
и они тоже снабжаются своими тестами. Чтобы выполнить их все,
+
and they also supplied with their tests. To perform them all,
-
нужно ввести команду:
+
must enter the command:
-
python manage.py test
+
 python manage.py test
-
добавив предварительно в главный файл URL-карт следующие
+
adding previously in the main file the following URL-card
-
строки:
+
lines:
-
<source lang="python">urlpatterns += patterns('django.contrib.auth.views',
+
<source lang="python"> urlpatterns + = patterns ('django.contrib.auth.views',
-
url(r'^auth/password_reset/$','password_reset'),
+
url (r '^ auth / password_reset /$',' password_reset'),
-
)</source>
+
) </ Source>
-
Здесь мы подключаем одно из встроенных представлений, предназначенное для восстановления пароля. Это необходимо, так как при
+
Here we include one of the built-in views, designed to recover your password. This is necessary since
-
тестировании всего проекта происходит обращение по указанному URL,
+
testing of the entire project is being accessed at the specified URL,
-
и если представление не определено, тест будет провален. Кстати, вы
+
and if the view is not specified, the test will fail. By the way, you
-
тоже можете попробовать password_reset в работе (рис. 2).
+
also can try password_reset in (Fig. 2).
-
[[Изображение:LXF108 85 2.png|frame|center|Рис. 2. Забыли пароль? Это проблемы Django!]]
+
[[Image: LXF108 85 2.png | frame | center | Fig. 2. Forgot your password? This problem Django!]]
-
=== Имитатор Сети ===
+
=== === Network Simulator
-
Количество тестов уже достигло шести, но помимо создания и
+
The number of tests has already reached six, but in addition to creating and
-
извлечения объектов из базы, нам нужно проверить реакцию на
+
retrieve objects from the database, we need to test the response to
-
GET- и POST-запросы. Как вы знаете, для этих целей существует
+
GET-and POST-requests. As you know, for these purposes there
-
специальный клиент: он эмулирует запрос и возвращает переменные, которые передаются в шаблон для данного URL. Добавьте в
+
special client: it emulates the query and returns the variables that are passed to the template for this URL. Add the
-
файл tests.py после строки 10 следующий код:
+
tests.py file after line 10 the following code:
<source lang="python" line="GESHI_NORMAL_LINE_NUMBERS" line start="11">
<source lang="python" line="GESHI_NORMAL_LINE_NUMBERS" line start="11">
-
>>> from django.contrib.auth.models import User
+
>>> From django.contrib.auth.models import User
-
>>> user = User.objects.create_user('django_guru', 'user@example.com', 'password')
+
>>> User = User.objects.create_user ('django_guru', 'user@example.com', 'password')
-
>>> user.save()
+
>>> User.save ()
-
>>> from django.test.client import Client
+
>>> From django.test.client import Client
-
>>> c = Client()
+
>>> C = Client ()
-
>>> c.login(username='django_guru',password=“password”)
+
>>> C.login (username = 'django_guru', password = "password")
True
True
-
>>> response = c.get('/news/1/')
+
>>> Response = c.get ('/ news / 1 /')
-
>>> response.status_code
+
>>> Response.status_code
200
200
-
>>> print response.context[0]['user'].username
+
>>> Print response.context [0] ['user']. Username
django_guru
django_guru
-
>>> response = c.post('/news/1/',{'username':“testuser”,'text':»»})
+
>>> Response = c.post ('/ news / 1 /',{' username': "testuser", 'text':»»})
-
>>> response.status_code
+
>>> Response.status_code
200
200
-
>>> response = c.post('/news/1/',{'username':“testuser”,'text':»Comment text»})
+
>>> Response = c.post ('/ news / 1 /',{' username': "testuser", 'text': »Comment text»})
-
>>> response.status_code
+
>>> Response.status_code
302
302
-
>>> from news.models import Comment
+
>>> From news.models import Comment
-
>>> comment = Comment.objects.get(news=news)
+
>>> Comment = Comment.objects.get (news = news)
-
>>> print comment.text
+
>>> Print comment.text
-
Comment text</source>
+
Comment text </ source>
-
Разберемся, что здесь происходит. В строках 11–13 мы создаем
+
See what is happening here. In lines 11-13 we create
-
нового пользователя (django_guru), а в 14–15 – тестовый клиент. В
+
New User (django_guru), and in 14-15 - the test client. In
-
строке 16 django_guru авторизуется, и отныне все действия в системе
+
line 16 django_guru authenticated, and now all of the system
-
будут совершаться от его имени. В строке 18 мы переходим на страницу нашей первой новости, передав средствами клиента GET-запрос.
+
will be performed by [http://www.mycaal.com loan modification] in his name. On line 18 we went to our first news page, passing the client means GET-request.
-
Для проверки, что нам это удалось, мы изучаем код ответа сервера
+
To check that we have succeeded, we study the server response code
-
(строка 19) – он должен равняться 200, или тест будет провален.
+
(Line 19) - it should be 200, or test will fail.
-
Затем (строки 21–22), чтением дополнительных данных ответа, мы
+
Then (lines 21-22), the reading of additional response data, we
-
убеждаемся, что запрос сделал зарегистрированный пользователь
+
verify that the request is made a registered user
-
django_guru. Теперь самое время оставить комментарий – не зря же
+
django_guru. Now it's time to leave a comment - not in vain
-
мы авторизовались? В строке 23 генерируется POST-запрос (второй
+
We logged in? Line 23 is generated POST-request (second
-
аргумент метода post() – словарь отсылаемых на сервер данных).
+
argument to post () - dictionary data sent to the server).
-
Обратите внимание, что значение ключа text оставлено пустым, а
+
Note that the value of the key text is blank, and
-
значит, комментарий не добавится, однако сервер по-прежнему должен возвращать код 200 (строка 25). А вот в строке 26 мы передаем
+
hence, the comment is not added, but the server still must return code 200 (line 25). But in line 26 we pass
-
все необходимые данные, и так как после создания комментария нас
+
all necessary data, and because after the comment we
-
перенаправляют на страницу новости, код ответа должен быть равен
+
redirected to the news page, the response code should be equal
-
302 (Требуемый URL перемещен). В строках 29–32 проверяется, что
+
302 (The requested URL moved). Lines 29-32 verify that
-
комментарий был действительно добавлен: мы сравниваем его текст
+
comment was actually added, we compare the text
-
с исходным значением. Уфф... тест пройден.
+
with an initial value. Whew ... test passed.
-
=== Действительно простая синдикация ===
+
Real Simple Syndication === ===
-
Какой новостной сайт без ленты? RSS и/или Atom есть везде – будут
+
What is a news site without the tape? RSS and / or Atom feeds are everywhere - will be
-
и у нас, а Django нам в этом поможет. Откройте главный файл URL-карт и добавьте в его конец следующие строки:
+
and here, and Django us help you. Open the main file URL-cards and add to the end of the following lines:
<source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
<source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
from feeds import LatestNews
from feeds import LatestNews
feeds = {
feeds = {
-
'latest': LatestNews,
+
'Latest': LatestNews,
}
}
-
urlpatterns += patterns('',
+
urlpatterns + = patterns ('',
-
(r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',
+
(R '^ feeds / (? P <url> .*)/$',' django.contrib.syndication.views.feed ',
-
{'feed_dict': feeds}),
+
{'Feed_dict': feeds}),
)
)
-
</source>
+
</ Source>
-
Далее нужно приготовить ленту LatestNews, которую мы импортируем в строке 1. Создайте в корне проекта каталог feeds с файлом
+
Next you need to prepare a tape LatestNews, which we import at row 1. Create the root directory of the project feeds the file
-
__init__.py следующего содержания:
+
__init__.py as follows:
<source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
<source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
-
# -*- coding: utf-8 -*-
+
# -*- Coding: utf-8 -*-
from django.contrib.syndication.feeds import Feed
from django.contrib.syndication.feeds import Feed
Строка 151: Строка 151:
from django.contrib.syndication.feeds import FeedDoesNotExist
from django.contrib.syndication.feeds import FeedDoesNotExist
-
class LatestNews(Feed):
+
class LatestNews (Feed):
-
title = "Последние новости нашего сайта"
+
title = "Latest news from our site"
-
description = "Последние события на сайте mysite.com"
+
description = "Recent developments on the site mysite.com"
link = "http://127.0.0.1:8000/news/"
link = "http://127.0.0.1:8000/news/"
-
def items(self):
+
def items (self):
-
return News.objects.order_by("-pub_date")[:5]
+
return News.objects.order_by ("-pub_date") [: 5]
-
def item_link(self, obj):
+
def item_link (self, obj):
from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse
-
return 'http://127.0.0.1:8000%s' % reverse('news.news_detail',kwargs={"news_id":obj.pk})
+
return 'http://127.0.0.1:8000% s'% reverse ('news.news_detail', kwargs = {"news_id": obj.pk})
-
</source>
+
</ Source>
-
[[Изображение:LXF108 86 1.png|thumb|250px|Рис. 3. Firefox предлагает подписаться на обновления нашего новостного сайта – теперь держитесь!]]
+
[[Image: LXF108 86 1.png | thumb | 250px | Fig. 3. Firefox offers to subscribe to our news website updated - now hold on!]]
-
Поля title, description и link класса LatestNews являются обязательными и отвечают за одноименные элементы RSS. Метод items()
+
Fields title, description and link class LatestNews are required and are responsible for elements of the same name RSS. The method items ()
-
передает в ленту требуемые объекты, а item_link() отвечает за ссылку
+
passes the required objects in the tape, and item_link () is responsible for the link
-
на сайт. Теперь создайте каталог feeds в media/templates и добавьте
+
to the site. Now create a directory of feeds media / templates, and add
-
в него два файла, latest_description.html и latest_title.html: они будут
+
in it two files, latest_description.html and latest_title.html: they will
-
отвечать за вид новостной ленты. В lates_description.html напишите:
+
responsible for the news column form. In lates_description.html write:
-
<nowiki>{{ obj.description }}</nowiki>
+
 <nowiki> {{obj.description}} </ nowiki>
-
а в latest_title.html:
+
and latest_title.html:
-
<nowiki>[{{ obj.pub_date|date:"d.m.Y" }}] {{ obj.title }}</nowiki>
+
 <nowiki> [{{obj.pub_date | date: "dmY"}}] {{obj.title}} </ nowiki>
-
Объект obj представляет собой запись из выборки, которую мы
+
Obj is a record of the sample, we
-
возвращаем в строке 13 файла feeds/__init__.py. Пройдя по адресу
+
return in line 13, file feeds / __init__.py. Having at
-
http://127.0.0.1:8000/feeds/latest/, мы увидим предложение Firefox
+
http://127.0.0.1:8000/feeds/latest/, we shall offer Firefox
-
сохранить ленту новостей. Пользователи KDE, вероятно, предпочтут
+
save feed. Members KDE, is likely to prefer
-
Akregator – с ним тоже нет никаких проблем (рис. 3, 4)
+
Akregator - with him, too, there is no problem (Fig. 3, 4)
-
=== Общие представления ===
+
=== === Understanding
-
Чтобы облегчить жизнь web-разработчика, Django включил большое
+
To make life easier for web-developer, Django has included a large
-
число представлений для решения стандартных задач. Так, добавив
+
number of representations to solve standard problems. For example, adding
-
в главный файл URL-карт следующий код:
+
in the main file URL-mapping the following code:
<source lang="python">
<source lang="python">
from django.views.generic.list_detail import object_list
from django.views.generic.list_detail import object_list
from news.models import News
from news.models import News
-
urlpatterns += patterns('',
+
urlpatterns + = patterns ('',
-
('^lastnews/$', object_list, {
+
('^ Lastnews / $', object_list, {
-
'queryset': News.objects.all().order_by('-pub_date')[:10],
+
'Queryset': News.objects.all (). Order_by ('-pub_date') [: 10]
-
'template_name':'news/last_news.html',
+
'Template_name': 'news / last_news.html',
-
'template_object_name':'last_news'})
+
'Template_object_name': 'last_news'})
-
)</source>
+
) </ Source>
-
а также заменив в файле news/templates/news/last_news.html
+
as well as replacing the file in news / templates / news / last_news.html
-
{% for news in last_news %}
+
 {% For news in last_news%}
-
на
+
on
-
{% for news in last_news_list %}
+
 {% For news in last_news_list%}
-
мы сможем просматривать последние новости по адресу
+
we will be able to view the latest news at
-
http://127.0.0.1:8000/lastnews/, не вызывая представление news.last_news. Чтобы сделать доступными оба варианта, нужно найти в представлении news.last_news строку
+
http://127.0.0.1:8000/lastnews/, causing no idea news.last_news. To make available both options must be found in presenting the line news.last_news
-
"last_news":news,
+
 "Last_news": news,
-
и заменить ее на
+
and replace it with
-
"last_news_list":news,
+
 "Last_news_list": news,
-
Как вы уже догадались, общее представление object_list предназначено для работы со списком объектов. Еще есть представления для
+
As you may have guessed, the general idea object_list designed to work with a list of objects. Still there is a submission for
-
вывода объектов в зависимости от даты (django.views.generic.date_based.*), что позволяет очень просто создавать архивы записей:
+
O objects, depending on the date (django.views.generic.date_based .*), which makes it very easy to create backups of records:
-
* archive_index – вывод последних объектов, добавленных в базу данных;
+
* Archive_index - withdrawal of the last object added to the database;
-
* archive_{year,month,week,day,today} – вывод всех объектов за определенный год, месяц, неделю, день или за сегодня;
+
* Archive_ {year, month, week, day, today} - the output of all the objects in a given year, month, week, day or today;
-
* object_detail – вывод одного объекта за определенный день.
+
* Object_detail - the output of one object for a particular day.
-
Доступны общие представления для создания, обновления и
+
General ideas are available for creating, updating and
-
удаления объектов. Все они работают немного быстрее, чем созданные вручную, но позволяют решать лишь самые элементарные задачи. Если данные в вашем приложении выбираются из нескольких
+
deleting objects. They all work a little faster than by hand, but can solve only the most basic tasks. If the data in your application are selected from several
-
таблиц и это сопровождается расчетами, то общие представления
+
tables and is accompanied by the calculations, the overall presentation
-
не помогут – на то они и общие.
+
will not help - then, they are common.
-
=== Добавляем переменные на лету ===
+
=== Add === variables on the fly
-
В глубинах Django скрываются глобальные контекстные процессоры, основная задача которых – снабжать шаблоны переменными
+
In the depths of the global context Django hide processors, the main task - to supply the template variables
-
и объектами. Узнать, какие из них подключены, можно в кортеже
+
and objects. Learn which ones are connected, you can in a tuple
-
TEMPLATE_CONTEXT_PROCESSORS в файле settings.py. Например, у
+
TEMPLATE_CONTEXT_PROCESSORS in your settings.py. For example,
-
нас сейчас работают следующие процессоры:
+
We are now working the following processors:
-
* auth – информация о пользователе: объект user, его права доступа и сообщения, которые были ему отправлены;
+
* Auth - information about the user: the object user, his rights of access and the messages that were sent to him;
-
* i18n – сведения о текущем языке сайта и клиента;
+
* I18n - information about the current language of the site and the client;
-
* request – данные о запросе.
+
* Request - information on request.
-
Кроме них, существует еще процессор debug, передающий в
+
Besides them, there is a processor debug, sending in
-
шаблон данные о выполненных SQL-запросах, плюс мы можем
+
pattern data of the executed SQL-queries, plus we can
-
написать свой собственный! Для этого создадим в корне нашего
+
write your own! To do this we create in the root of our
-
проекта каталог processors и добавим в него два файла: __init__.py
+
project directory and add the processors in it two files: __init__.py
-
и context_processors.py. Последний должен содержать такой код:
+
and context_processors.py. The latter should contain the following code:
<source lang="python">
<source lang="python">
import settings
import settings
-
def site_settings(request):
+
def site_settings (request):
-
return {'SETTINGS': settings}</source>
+
return {'SETTINGS': settings} </ source>
-
Чтобы подключить процессор, просто перечислите его в кортеже
+
To connect the processor, just list it in the tuple
-
TEMPLATE_CONTEXT_PROCESSORS. Проверим работоспособность:
+
TEMPLATE_CONTEXT_PROCESSORS. We check availability:
-
добавим в шаблон news.html следующее:
+
add a template news.html following:
-
<nowiki>{{ SETTINGS.TIME_ZONE }}</nowiki>
+
 <nowiki> {{SETTINGS.TIME_ZONE}} </ nowiki>
-
Конечно, TIME_ZONE можно заменить на любую другую переменную, определенную в settings.py.
+
Of course, TIME_ZONE can be replaced by any other variable that is defined in settings.py.
-
=== Сам себе фильтр ===
+
=== === Sam himself filter
-
С фильтрами мы познакомились еще в [[LXF105:Django|LXF105]], однако часто возникают ситуации, когда поставляемых с Django вариантов недостаточно. Чтобы написать свой собственный фильтр, создайте в корне
+
With filters we met in [[LXF105: Django | LXF105]], but often there are situations when supplied with Django options are not enough. To write your own filter, create a radically
-
проекта каталог templatetags/ и добавьте в него файлы __init__.py
+
project directory templatetags / and add the files __init__.py
-
и filters.py. В filters.py напишите:
+
and filters.py. In filters.py write:
<source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
<source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
from django import template
from django import template
-
register = template.Library()
+
register = template.Library ()
-
@register.filter
+
@ Register.filter
-
def exp(value, arg):
+
def exp (value, arg):
-
if value.isdigit() and arg.isdigit():
+
if value.isdigit () and arg.isdigit ():
-
return int(value)**int(arg)
+
return int (value) ** int (arg)
else:
else:
-
return '<span style=“color:red”>Error</span>'
+
return '<span style="color:red"> Error </ span>'
-
exp.is_safe = True</source >
+
exp.is_safe = True </ source>
-
Мы создали фильтр exp, который получает значение и показатель степени и возводит одно в другое; если аргументы не являются числами, генерируется ошибка. В строке 5 мы регистрируем
+
We have created a filter exp, which will have a value and an exponent and raises one another, if the arguments are not numbers, an error is generated. In line 5 we register
-
фильтр в системе с помощью декоратора. Строка 11 указывает,
+
filter in the system with the help of a decorator. Line 11 indicates
-
что exp может возвращать HTML-код. Поскольку (в целях безопасности) он автоматически экранируется (< и > заменяются на &amp;lt; и
+
that exp can return HTML-code. Because (for security), it automatically screened (<and> are replaced by &lt; and
-
&amp;gt; и т.д.), то, желая видеть чистый HTML, мы должны запретить
+
&gt; etc.), then, wanting to see pure HTML, we should prohibit
-
такое поведение вручную. Следующим шагом является подгрузка
+
this behavior manually. The next step is loading of
-
библиотеки фильтров в шаблон, для чего нужно добавить в него
+
library of filters to the template, which you need to add the
-
следующую строку:
+
the following line:
-
{% load filters %}
+
 {% Load filters%}
-
Вообще-то Django ищет созданные библиотеки шаблонов в корне приложения, поэтому наш фильтр пока не будет доступен. Это
+
In fact, Django looks for templates created by the library in the application root, so our filter still will not be available. It
-
не очень удобно, особенно если мы хотим использовать один и тот
+
not very convenient, especially if we want to use the
-
же фильтр во многих приложениях. Решение – создать для проекта
+
the same filter in many applications. The solution - to create a project
-
единую библиотеку, а в приложения помещать лишь символьные
+
single library, and put in applications merely symbolic
-
ссылки на нее.
+
references to it.
-
<source lang="bash">ln -s /var/www/myproject/templatetags/ /var/www/myproject/news/</source>
+
<source lang="bash"> ln-s / var / www / myproject / templatetags / / var / www / myproject / news / </ source>
-
Теперь проверим работу фильтра, добавив в какой-нибудь шаблон
+
Now test the filter by adding any template
-
строку.
+
line.
-
<nowiki>{{ "4"|exp:"4" }}</nowiki>
+
 <nowiki> {{"4" | exp: "4"}} </ nowiki>
-
Во время компиляции она будет заменена на 256. Если же мы
+
At compile time, it will be replaced by 256. If we
-
напишем
+
write
-
<nowiki>{{ "a"|exp:"4" }}</nowiki>
+
 <nowiki> {{"a" | exp: "4"}} </ nowiki>
-
то увидим слово «Error», выделенное красным цветом.
+
we see the word «Error», in red.
-
Кстати, если бы мы не указали в строке 11 фильтра exp.is_safe= True, можно было бы просто применить фильтр safe прямо в
+
By the way, if we did not specify a filter in line 11 exp.is_safe = True, you could simply apply the filter directly into the safe
-
шаблоне:
+
template:
-
<nowiki>{{ "a"|exp:"4"|safe }}</nowiki>
+
 <nowiki> {{"a" | exp: "4" | safe}} </ nowiki>
-
После регистрации фильтра в системе, информация о нем становится доступной по адресу http://127.0.0.1:8000/admin/doc/filters/
+
After registering a filter in the system, information about it becomes available at http://127.0.0.1:8000/admin/doc/filters/
-
(рис. 4)
+
(Fig. 4)
-
[[Изображение:LXF108 87 1.png|frame|center|Рис. 4. Система любезно подскажет, как использовать созданный вами фильтр.]]
+
[[Image: LXF108 87 1.png | frame | center | Fig. 4. The system politely tells you how to use the filter you created.]]
-
=== Компоненты ===
+
=== === The components of
-
Если нам надо выполнить какие-либо действия до или после того,
+
If we have to perform any action before or after
-
как будет вызвано представление, либо в случае ошибки, можно создать свой компонент (middleware) или воспользоваться
+
as would be caused by representation, or if an error occurs, you can create your own components (middleware), or use
-
поставляемым с Django. Мы уже делали это, когда изучали кэширование ([[LXF107:Django|LXF107]]). Напомню, что в файле settings.py есть кортеж
+
supplied with Django. We've already done this, when studied caching ([[LXF107: Django | LXF107]]). I recall that in the settings.py file is a tuple
-
MIDDLEWARE_CLASSES, который перечисляет компоненты, задействованные в проекте. У нас это:
+
MIDDLEWARE_CLASSES, which lists the components involved in the project. We are:
-
* django.middleware.common.CommonMiddleware Решает общие задачи: нормализует URL (добавляет префикс www и завершающий /), запрещает доступ к сайту определенным роботам, взаимодействует с Etag.
+
* Django.middleware.common.CommonMiddleware solve common problems: normalizes the URL (adds a www and the trailing /), prohibits access to the site specific robot interacts with Etag.
-
* django.contrib.sessions.middleware.SessionMiddleware Это сессии.
+
* Django.contrib.sessions.middleware.SessionMiddleware this session.
-
* django.contrib.auth.middleware.AuthenticationMiddleware А это – авторизация.
+
* Django.contrib.auth.middleware.AuthenticationMiddleware And this - authorization.
-
* django.middleware.doc.XViewMiddleware Используется для автоматического документирования Django.
+
* Django.middleware.doc.XViewMiddleware used for automatic documentation Django.
-
* django.middleware.locale.LocaleMiddleware Интернационализация.
+
* Django.middleware.locale.LocaleMiddleware Internationalization.
-
Помимо перечисленных выше, в Django доступны следующие
+
In addition to the above, the following are available in Django
-
компоненты (django.middleware.*):
+
components (django.middleware .*):
-
* gzip.GZipMiddleware Сжатие отправляемой страницы для экономии трафика.
+
* Gzip.GZipMiddleware compression sends the page to save bandwidth.
-
* http.ConditionalGetMiddleware Поддержка условных GET-запросов для работы с Last-Modified и Etag.
+
* Http.ConditionalGetMiddleware Support for conditional GET-requests to work with the Last-Modified and Etag.
-
* http.SetRemoteAddrFromForwardedFor Обратное проксирование.
+
* Http.SetRemoteAddrFromForwardedFor reverse proxying.
-
* cache.CacheMiddleware Тот самый кэш, с которым мы сталкивались на прошлом уроке.
+
* Cache.CacheMiddleware The same cache, which we encountered in the previous lesson.
-
* transaction.TransactionMiddleware Компонент для включения в SQL-запросы транзакционных конструкций: COMMIT, ROLLBACK.
+
* Transaction.TransactionMiddleware component for inclusion in SQL-queries of transaction structures: COMMIT, ROLLBACK.
-
Заметьте, что не все базы данных поддерживают транзакции.
+
Note that not all databases support transactions.
-
И, наконец, django.contrib.csrf.middleware.CsrfMiddleware, защищающее от CSRF-атак.
+
And finally, django.contrib.csrf.middleware.CsrfMiddleware, protecting against CSRF-attacks.
-
По сложившейся уже традиции, рассмотрим, как написать свой
+
It has become a tradition, consider how to write your
-
собственный компонент. С точки зрения программиста, это просто
+
own components. From a programmer's standpoint, it's just
-
класс Python, имеющий ряд методов, вызываемых Django в определенные моменты времени. Первым из них является конструктор
+
Class Python, having a number of methods called Django at some point in time. The first is the constructor
-
__init__(self), регистрирующий компонент в системе. Дальше следуют методы, определяющие порядок выполнения кода:
+
__init__ (self), registering the components in the system. Next are the methods of determining the order of the code:
-
* process_request() – запускается после того, как поступил запрос,но перед тем как Django начнет искать запрашиваемый адрес в URL-картах;
+
* Process_request () - runs after the request, but before Django will look for the requested address in the URL-maps;
-
* process_view() – отрабатывает, когда конкретное представление уже определено, но еще не запущено;
+
* Process_view () - work out when the concrete representation is defined, but not yet started;
-
* process_response() – выполняется после представления.
+
* Process_response () - runs after the presentation.
-
Используется для сжатия сгенерированного HTML.
+
Used to compress the generated HTML.
-
process_exception() – вызывается, если что-то пошло не так или
+
process_exception () - called when something goes wrong or
-
было возбуждено необработанное исключение.
+
were instituted an unhandled exception.
-
Вот, в сущности, и все. Впрочем, нет – взгляните на врезку И
+
That is, in essence, that's all. But no - look at the sidebar and
-
прочая, прочая, прочая, почитайте документацию или свободную
+
away, away, away, read the documentation or the free
-
книгу о Django Django Book (http://www.djangobook.com); если же вам
+
a book about Django - Django Book (http://www.djangobook.com); if you
-
больше по душе русский, советую заглянуть на http://cargo.caml.ru/djangobook. Наконец, примените полученные знания на практике – и дайте нам знать, если у вас получится что-то действительно стоящее!
+
prefer Russian, I advise you to look at http://cargo.caml.ru/djangobook. Finally, apply the acquired knowledge into practice - and let us know if you have something really worthwhile!
-
{{Врезка|center|
+
{{Box | center |
-
|Заголовок=И прочая, прочая, прочая...
+
| Title =, etc., etc., other ...
-
|Содержание=За четыре урока мы успели рассмотреть почти все возможности
+
| Table of Contents = Over four lessons, we had to consider almost all possible
-
Django, но кое-что осталось неохваченным...
+
Django, but something is left out ...
-
*; Электронная почта
+
*, E-mail
-
Django предлагает высокоуровневый API для отправки письма в
+
Django offers a high-level API to send a message to
-
одно действие:
+
one action:
-
<source lang="python">from django.core.mail import send_mail
+
<source lang="python"> from django.core.mail import send_mail
-
send_mail('Тема', 'сообщение.', 'from@example.com', ['to@example.com'], fail_silently=False)</source>
+
send_mail ('Subject', 'message.', 'from@example.com', ['to@example.com'], fail_silently = False) </ source>
-
Кроме того, есть функции массовой рассылки сообщений, оповещения администраторов и менеджеров сайта, а также работы с
+
In addition, there is a function of mass communications, alerts, site administrators and managers, as well as working with
-
различным содержимым (HTML, текст, графика и т.п.)
+
different content (HTML, text, graphics, etc.)
-
*; CSV и PDF
+
*; CSV and PDF
-
Django позволяет легко формировать файлы с данными, разделенными запятыми (CSV), а также PDF-документы, используя
+
Django makes it easy to create data files, Comma Separated Values ​​(CSV), as well as PDF-documents using
-
библиотеку ReportLab (http://www.reportlab.org/rl_toolkit.html).
+
Library ReportLab (http://www.reportlab.org/rl_toolkit.html).
-
*; Постраничный вывод
+
*, Paged
-
Когда количество объектов настолько велико, что одной страницы становится мало, на помощь приходит специальный класс
+
When the number of objects is so large that one page is enough, have the support of a special class
-
Paginator, который помогает организовать постраничный вывод:
+
Paginator, who helps organize paged:
<source lang="python">>>> from django.core.paginator import Paginator
<source lang="python">>>> from django.core.paginator import Paginator
-
>>> objects = ['django', 'python', 'mysql', 'apache']
+
>>> Objects = ['django', 'python', 'mysql', 'apache']
-
>>> p = Paginator(objects, 2)
+
>>> P = Paginator (objects, 2)
-
>>> page1 = p.page(1)
+
>>> Page1 = p.page (1)
-
>>> page1.object_list
+
>>> Page1.object_list
-
['django', 'python']</source>
+
['Django', 'python'] </ source>
-
Поскольку большинство наших объектов хранятся в базе данных,
+
Since most of our objects are stored in the database,
-
Django также предлагает класс QuerySetPaginator, который принимает не список, а множество объектов из СУБД.
+
Django also offers class QuerySetPaginator, which takes no list, and many objects from the database.
-
*; Карты сайта
+
*; Sitemaps
-
Хотите, чтобы ваш сайт правильно индексировался поисковыми
+
Want to have your site properly indexed by search
-
машинами? Необходимо создать его карту! Django поможет и
+
machines? You need to create his map! Django will help
-
здесь, а функция django.contrib.sitemaps.ping_google «заставит»
+
here, and the function django.contrib.sitemaps.ping_google «cause»
-
Google обновить индексы для вашего сайта.
+
Google to update the index for your website.
-
*; Управление несколькими сайтами
+
; * Managing multiple sites
-
Одной из задач, с которой успешно справляется Django, является
+
One of the problems with which copes Django, is
-
управление несколькими схожими по тематике сайтами из одной
+
control of several similar sites on the subject of a
-
инсталляции. Проект первоначально разрабатывался как платформа для новостных порталов, и одна новость могла появиться
+
installation. The project was originally designed as a platform for news portals, news, and one could appear
-
сразу на нескольких ресурсах.
+
on multiple resources.
-
*; В помощь дизайнерам
+
*; To help designers
-
Подгрузив к шаблонам модуль помощи дизайнерам:
+
Load the module templates to help designers:
-
{% load webdesign %}
+
 {% Load webdesign%}
-
вы получите в свое распоряжение тэг {% lorem %}, с помощью
+
you get at your disposal tag {% lorem%}, with
-
которого можно выводить известную латинскую фразу «lorem
+
which you can display certain Latin phrase «lorem
-
ipsum ...» для заполнения шаблонов «рыбой».
+
ipsum ... »to fill the template" fish. "
-
*; И более того
+
; * And more
-
Django содержит много других «вкусностей», которые очень
+
Django has a lot of other "goodies" that are very
-
хорошо описаны в прилагающейся документации на английском
+
well described in the accompanying documentation in English
-
языке.
+
language.
-
|Ширина=}}
+
| Width =}}

Версия 08:02, 20 июля 2011

Cycle Шаблон:/ Django == == The final touches

PART 4 ​​Lessons Django comes to an end, there comes a time for exams - if not for you, for applications for sure. Nikita Shultays (http://shultais.ru) will deal with testing and go over other features of this framework.

Newsline is ready - but whether it will meet expectations users? The answer to this question can be tested, the best - in the real world, but some basic things you can check at the stage of development thesis writers. If you time to look at the tutorial Rails, you already know about the methodology of TDD. However, we'll go the other way, and will test application not to write, and after.

The point is - a serious and complex, as we need to consider interaction with the database, a compilation of templates, processes and GET- POST-requests and other system components: a failure in any of They can cause disrupt the entire site. Go to this problem can be approached from two sides:

  • Testing in your browser. We are talking about programs Twill (http://twill.idyll.org) and Selenium (http://selenium.openqa.org): they "remember" the sequence of your actions for each page, and then reproduce it on demand. For example, you can type in form fields obviously incorrect data, get the expected error and repeat the test whenever a major change in the code of your application.
  • Testing on the server. And then Django does not leave us to fend for themselves, offering just two options: doctest (tested via documentation) and unittest (unit testing), plus a special client to send a GET-and POST-requests.

If you've been programming in Python, then you probably will be closer doctest, and migrants from the Java world have more in taste unittest. There are no restrictions on their use is imposed: you can choose one system or use both at once. We also discuss the doctest.

Document it!

Line documentation in Python - it is plain text that you place after the definition of a function or class directly in the source code. It also provides content for the attribute __doc__. As Typically, it is placed in triple quotes ("""), that allows you to enter complex structures with line breaks, indentation, the same quotes and ... tests. That's what we use.

Tests can be found in the model files (models.py) - to check the latest - and in special files tests.py, located in the application directory. For example, create a news / tests.py to the following:

  1. # -*- Coding: utf-8 -*-
  2.  
  3. "" "
  4. >>> From news.models import News
  5. >>> From datetime import datetime
  6. >>> News = News (title = "Title", description = "Description", pub_date = datetime.now (), text = "text")
  7. >>> News.save ()
  8. >>> News = News.objects.get (pk = 1)
  9. >>> Print news.title.encode ('utf-8')
  10.  Title
  11. "" "
  12. </ Source>
  13. In line 1 encoding, but since the third is very
  14. test. Note that each line begins with three characters "more" (>>>), in the interactive mode, Python. Line 10
  15. These characters do not, because it contains the expected output
  16. print from line 9.
  17.  
  18. [[Image: LXF108 85 1.png | thumb | 200px | Fig. 1. Test passed successfully!]]
  19. Before running the test, you need to add in settings.py
  20. line
  21.  TEST_DATABASE_CHARSET = "UTF8"
  22. to file encoding and the database match. Before performing the test, Django will create a special auxiliary databases, so
  23. the user specified in settings.DATABASE_USER, must have
  24. the appropriate authority. To begin testing, type:
  25.  python manage.py test news
  26. after which you will see something that shows
  27. Fig. 1.
  28.  
  29. Messages similar to appear during the creation of tables
  30. when you first install, but now it happens in a test database. In
  31. end shows the number of tests performed, their results and
  32. notified about the destruction of a test material. We checked our
  33. application (news), but, as you know, Django provides a few
  34. own applications and representations (eg, "admin") -
  35. and they also supplied with their tests. To perform them all,
  36. must enter the command:
  37.  python manage.py test
  38. adding previously in the main file the following URL-card
  39. lines:
  40. <source lang="python"> urlpatterns + = patterns ('django.contrib.auth.views',
  41. url (r '^ auth / password_reset /$',' password_reset'),
  42. ) </ Source>
  43. Here we include one of the built-in views, designed to recover your password. This is necessary since
  44. testing of the entire project is being accessed at the specified URL,
  45. and if the view is not specified, the test will fail. By the way, you
  46. also can try password_reset in (Fig. 2).
  47. [[Image: LXF108 85 2.png | frame | center | Fig. 2. Forgot your password? This problem Django!]]
  48.  
  49. === === Network Simulator
  50. The number of tests has already reached six, but in addition to creating and
  51. retrieve objects from the database, we need to test the response to
  52. GET-and POST-requests. As you know, for these purposes there
  53. special client: it emulates the query and returns the variables that are passed to the template for this URL. Add the
  54. tests.py file after line 10 the following code:
  55. <source lang="python" line="GESHI_NORMAL_LINE_NUMBERS" line start="11">
  56. >>> From django.contrib.auth.models import User
  57. >>> User = User.objects.create_user ('django_guru', 'user@example.com', 'password')
  58. >>> User.save ()
  59. >>> From django.test.client import Client
  60. >>> C = Client ()
  61. >>> C.login (username = 'django_guru', password = "password")
  62. True
  63. >>> Response = c.get ('/ news / 1 /')
  64. >>> Response.status_code
  65. 200
  66. >>> Print response.context [0] ['user']. Username
  67. django_guru
  68. >>> Response = c.post ('/ news / 1 /',{' username': "testuser", 'text':»»})
  69. >>> Response.status_code
  70. 200
  71. >>> Response = c.post ('/ news / 1 /',{' username': "testuser", 'text': »Comment text»})
  72. >>> Response.status_code
  73. 302
  74. >>> From news.models import Comment
  75. >>> Comment = Comment.objects.get (news = news)
  76. >>> Print comment.text
  77. Comment text </ source>
  78. See what is happening here. In lines 11-13 we create
  79. New User (django_guru), and in 14-15 - the test client. In
  80. line 16 django_guru authenticated, and now all of the system
  81. will be performed by [http://www.mycaal.com loan modification] in his name. On line 18 we went to our first news page, passing the client means GET-request.
  82. To check that we have succeeded, we study the server response code
  83. (Line 19) - it should be 200, or test will fail.
  84. Then (lines 21-22), the reading of additional response data, we
  85. verify that the request is made a registered user
  86. django_guru. Now it's time to leave a comment - not in vain
  87. We logged in? Line 23 is generated POST-request (second
  88. argument to post () - dictionary data sent to the server).
  89. Note that the value of the key text is blank, and
  90. hence, the comment is not added, but the server still must return code 200 (line 25). But in line 26 we pass
  91. all necessary data, and because after the comment we
  92. redirected to the news page, the response code should be equal
  93. 302 (The requested URL moved). Lines 29-32 verify that
  94. comment was actually added, we compare the text
  95. with an initial value. Whew ... test passed.
  96.  
  97. Real Simple Syndication === ===
  98. What is a news site without the tape? RSS and / or Atom feeds are everywhere - will be
  99. and here, and Django us help you. Open the main file URL-cards and add to the end of the following lines:
  100. <source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
  101. from feeds import LatestNews
  102.  
  103. feeds = {
  104. 'Latest': LatestNews,
  105. }
  106. urlpatterns + = patterns ('',
  107. (R '^ feeds / (? P <url> .*)/$',' django.contrib.syndication.views.feed ',
  108. {'Feed_dict': feeds}),
  109. )
  110. </ Source>
  111. Next you need to prepare a tape LatestNews, which we import at row 1. Create the root directory of the project feeds the file
  112. __init__.py as follows:
  113. <source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
  114. # -*- Coding: utf-8 -*-
  115.  
  116. from django.contrib.syndication.feeds import Feed
  117. from news.models import News
  118. from django.contrib.syndication.feeds import FeedDoesNotExist
  119.  
  120. class LatestNews (Feed):
  121. title = "Latest news from our site"
  122. description = "Recent developments on the site mysite.com"
  123. link = "http://127.0.0.1:8000/news/"
  124.  
  125. def items (self):
  126. return News.objects.order_by ("-pub_date") [: 5]
  127.  
  128. def item_link (self, obj):
  129. from django.core.urlresolvers import reverse
  130. return 'http://127.0.0.1:8000% s'% reverse ('news.news_detail', kwargs = {"news_id": obj.pk})
  131. </ Source>
  132. [[Image: LXF108 86 1.png | thumb | 250px | Fig. 3. Firefox offers to subscribe to our news website updated - now hold on!]]
  133. Fields title, description and link class LatestNews are required and are responsible for elements of the same name RSS. The method items ()
  134. passes the required objects in the tape, and item_link () is responsible for the link
  135. to the site. Now create a directory of feeds media / templates, and add
  136. in it two files, latest_description.html and latest_title.html: they will
  137. responsible for the news column form. In lates_description.html write:
  138.  <nowiki> {{obj.description}} </ nowiki>
  139. and latest_title.html:
  140.  <nowiki> [{{obj.pub_date | date: "dmY"}}] {{obj.title}} </ nowiki>
  141. Obj is a record of the sample, we
  142. return in line 13, file feeds / __init__.py. Having at
  143. http://127.0.0.1:8000/feeds/latest/, we shall offer Firefox
  144. save feed. Members KDE, is likely to prefer
  145. Akregator - with him, too, there is no problem (Fig. 3, 4)
  146.  
  147. === === Understanding
  148. To make life easier for web-developer, Django has included a large
  149. number of representations to solve standard problems. For example, adding
  150. in the main file URL-mapping the following code:
  151. <source lang="python">
  152. from django.views.generic.list_detail import object_list
  153. from news.models import News
  154. urlpatterns + = patterns ('',
  155. ('^ Lastnews / $', object_list, {
  156. 'Queryset': News.objects.all (). Order_by ('-pub_date') [: 10]
  157. 'Template_name': 'news / last_news.html',
  158. 'Template_object_name': 'last_news'})
  159. ) </ Source>
  160. as well as replacing the file in news / templates / news / last_news.html
  161.  {% For news in last_news%}
  162. on
  163.  {% For news in last_news_list%}
  164. we will be able to view the latest news at
  165. http://127.0.0.1:8000/lastnews/, causing no idea news.last_news. To make available both options must be found in presenting the line news.last_news
  166.  "Last_news": news,
  167. and replace it with
  168.  "Last_news_list": news,
  169. As you may have guessed, the general idea object_list designed to work with a list of objects. Still there is a submission for
  170. O objects, depending on the date (django.views.generic.date_based .*), which makes it very easy to create backups of records:
  171. * Archive_index - withdrawal of the last object added to the database;
  172. * Archive_ {year, month, week, day, today} - the output of all the objects in a given year, month, week, day or today;
  173. * Object_detail - the output of one object for a particular day.
  174. General ideas are available for creating, updating and
  175. deleting objects. They all work a little faster than by hand, but can solve only the most basic tasks. If the data in your application are selected from several
  176. tables and is accompanied by the calculations, the overall presentation
  177. will not help - then, they are common.
  178.  
  179. === Add === variables on the fly
  180. In the depths of the global context Django hide processors, the main task - to supply the template variables
  181. and objects. Learn which ones are connected, you can in a tuple
  182. TEMPLATE_CONTEXT_PROCESSORS in your settings.py. For example,
  183. We are now working the following processors:
  184. * Auth - information about the user: the object user, his rights of access and the messages that were sent to him;
  185. * I18n - information about the current language of the site and the client;
  186. * Request - information on request.
  187. Besides them, there is a processor debug, sending in
  188. pattern data of the executed SQL-queries, plus we can
  189. write your own! To do this we create in the root of our
  190. project directory and add the processors in it two files: __init__.py
  191. and context_processors.py. The latter should contain the following code:
  192. <source lang="python">
  193. import settings
  194. def site_settings (request):
  195. return {'SETTINGS': settings} </ source>
  196. To connect the processor, just list it in the tuple
  197. TEMPLATE_CONTEXT_PROCESSORS. We check availability:
  198. add a template news.html following:
  199.  <nowiki> {{SETTINGS.TIME_ZONE}} </ nowiki>
  200. Of course, TIME_ZONE can be replaced by any other variable that is defined in settings.py.
  201.  
  202. === === Sam himself filter
  203. With filters we met in [[LXF105: Django | LXF105]], but often there are situations when supplied with Django options are not enough. To write your own filter, create a radically
  204. project directory templatetags / and add the files __init__.py
  205. and filters.py. In filters.py write:
  206. <source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
  207. from django import template
  208.  
  209. register = template.Library ()
  210.  
  211. @ Register.filter
  212. def exp (value, arg):
  213. if value.isdigit () and arg.isdigit ():
  214. return int (value) ** int (arg)
  215. else:
  216. return '<span style="color:red"> Error </ span>'
  217. exp.is_safe = True </ source>
  218. We have created a filter exp, which will have a value and an exponent and raises one another, if the arguments are not numbers, an error is generated. In line 5 we register
  219. filter in the system with the help of a decorator. Line 11 indicates
  220. that exp can return HTML-code. Because (for security), it automatically screened (<and> are replaced by &lt; and
  221. &gt; etc.), then, wanting to see pure HTML, we should prohibit
  222. this behavior manually. The next step is loading of
  223. library of filters to the template, which you need to add the
  224. the following line:
  225.  {% Load filters%}
  226. In fact, Django looks for templates created by the library in the application root, so our filter still will not be available. It
  227. not very convenient, especially if we want to use the
  228. the same filter in many applications. The solution - to create a project
  229. single library, and put in applications merely symbolic
  230. references to it.
  231. <source lang="bash"> ln-s / var / www / myproject / templatetags / / var / www / myproject / news / </ source>
  232. Now test the filter by adding any template
  233. line.
  234.  <nowiki> {{"4" | exp: "4"}} </ nowiki>
  235. At compile time, it will be replaced by 256. If we
  236. write
  237.  <nowiki> {{"a" | exp: "4"}} </ nowiki>
  238. we see the word «Error», in red.
  239. By the way, if we did not specify a filter in line 11 exp.is_safe = True, you could simply apply the filter directly into the safe
  240. template:
  241.  <nowiki> {{"a" | exp: "4" | safe}} </ nowiki>
  242. After registering a filter in the system, information about it becomes available at http://127.0.0.1:8000/admin/doc/filters/
  243. (Fig. 4)
  244. [[Image: LXF108 87 1.png | frame | center | Fig. 4. The system politely tells you how to use the filter you created.]]
  245.  
  246. === === The components of
  247. If we have to perform any action before or after
  248. as would be caused by representation, or if an error occurs, you can create your own components (middleware), or use
  249. supplied with Django. We've already done this, when studied caching ([[LXF107: Django | LXF107]]). I recall that in the settings.py file is a tuple
  250. MIDDLEWARE_CLASSES, which lists the components involved in the project. We are:
  251. * Django.middleware.common.CommonMiddleware solve common problems: normalizes the URL (adds a www and the trailing /), prohibits access to the site specific robot interacts with Etag.
  252. * Django.contrib.sessions.middleware.SessionMiddleware this session.
  253. * Django.contrib.auth.middleware.AuthenticationMiddleware And this - authorization.
  254. * Django.middleware.doc.XViewMiddleware used for automatic documentation Django.
  255. * Django.middleware.locale.LocaleMiddleware Internationalization.
  256. In addition to the above, the following are available in Django
  257. components (django.middleware .*):
  258. * Gzip.GZipMiddleware compression sends the page to save bandwidth.
  259. * Http.ConditionalGetMiddleware Support for conditional GET-requests to work with the Last-Modified and Etag.
  260. * Http.SetRemoteAddrFromForwardedFor reverse proxying.
  261. * Cache.CacheMiddleware The same cache, which we encountered in the previous lesson.
  262. * Transaction.TransactionMiddleware component for inclusion in SQL-queries of transaction structures: COMMIT, ROLLBACK.
  263. Note that not all databases support transactions.
  264.  
  265. And finally, django.contrib.csrf.middleware.CsrfMiddleware, protecting against CSRF-attacks.
  266.  
  267. It has become a tradition, consider how to write your
  268. own components. From a programmer's standpoint, it's just
  269. Class Python, having a number of methods called Django at some point in time. The first is the constructor
  270. __init__ (self), registering the components in the system. Next are the methods of determining the order of the code:
  271. * Process_request () - runs after the request, but before Django will look for the requested address in the URL-maps;
  272. * Process_view () - work out when the concrete representation is defined, but not yet started;
  273. * Process_response () - runs after the presentation.
  274. Used to compress the generated HTML.
  275. process_exception () - called when something goes wrong or
  276. were instituted an unhandled exception.
  277.  
  278. That is, in essence, that's all. But no - look at the sidebar and
  279. away, away, away, read the documentation or the free
  280. a book about Django - Django Book (http://www.djangobook.com); if you
  281. prefer Russian, I advise you to look at http://cargo.caml.ru/djangobook. Finally, apply the acquired knowledge into practice - and let us know if you have something really worthwhile!
  282.  
  283. {{Box | center |
  284. | Title =, etc., etc., other ...
  285. | Table of Contents = Over four lessons, we had to consider almost all possible
  286. Django, but something is left out ...
  287. *, E-mail
  288. Django offers a high-level API to send a message to
  289. one action:
  290. <source lang="python"> from django.core.mail import send_mail
  291. send_mail ('Subject', 'message.', 'from@example.com', ['to@example.com'], fail_silently = False) </ source>
  292. In addition, there is a function of mass communications, alerts, site administrators and managers, as well as working with
  293. different content (HTML, text, graphics, etc.)
  294. *; CSV and PDF
  295. Django makes it easy to create data files, Comma Separated Values ​​(CSV), as well as PDF-documents using
  296. Library ReportLab (http://www.reportlab.org/rl_toolkit.html).
  297. *, Paged
  298. When the number of objects is so large that one page is enough, have the support of a special class
  299. Paginator, who helps organize paged:
  300. <source lang="python">>>> from django.core.paginator import Paginator
  301. >>> Objects = ['django', 'python', 'mysql', 'apache']
  302. >>> P = Paginator (objects, 2)
  303. >>> Page1 = p.page (1)
  304. >>> Page1.object_list
  305. ['Django', 'python'] </ source>
  306. Since most of our objects are stored in the database,
  307. Django also offers class QuerySetPaginator, which takes no list, and many objects from the database.
  308. *; Sitemaps
  309. Want to have your site properly indexed by search
  310. machines? You need to create his map! Django will help
  311. here, and the function django.contrib.sitemaps.ping_google «cause»
  312. Google to update the index for your website.
  313. ; * Managing multiple sites
  314. One of the problems with which copes Django, is
  315. control of several similar sites on the subject of a
  316. installation. The project was originally designed as a platform for news portals, news, and one could appear
  317. on multiple resources.
  318. *; To help designers
  319. Load the module templates to help designers:
  320.  {% Load webdesign%}
  321. you get at your disposal tag {% lorem%}, with
  322. which you can display certain Latin phrase «lorem
  323. ipsum ... »to fill the template" fish. "
  324. ; * And more
  325. Django has a lot of other "goodies" that are very
  326. well described in the accompanying documentation in English
  327. language.
  328. | Width =}}
Личные инструменты
  • Купить электронную версию
  • Подписаться на бумажную версию