Журнал LinuxFormat - перейти на главную

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 =}}

Версия 11: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 =}}
Персональные инструменты
купить
подписаться
Яндекс.Метрика