- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF108:Django
Материал из Linuxformat.
(Отмена правки № 12588 участника Karencarter (обсуждение)) |
(Отмена правки № 12587 участника Karencarter (обсуждение)) |
||
Строка 349: | Строка 349: | ||
installation. The project was originally designed as a platform for news portals, news, and one could appear | installation. The project was originally designed as a platform for news portals, news, and one could appear | ||
on multiple resources. | on multiple resources. | ||
- | *; To help designers | + | *; To help designers |
Load the module templates to help designers: | Load the module templates to help designers: | ||
{% Load webdesign%} | {% Load webdesign%} |
Версия 13:16, 16 сентября 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,loan modification 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:
- # -*- Coding: utf-8 -*-
- "" "
- >>> From news.models import News
- >>> From datetime import datetime
- >>> News = News (title = "Title", description = "Description", pub_date = datetime.now (), text = "text")
- >>> News.save ()
- >>> News = News.objects.get (pk = 1)
- >>> Print news.title.encode ('utf-8')
- Title
- "" "
- </ Source>
- In line 1 encoding, but since the third is very
- 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 from line 9.
- [[Image: LXF108 85 1.png | thumb | 200px | Fig. 1. Test passed successfully!]]
- Before running the test, you need to add in settings.py
- line
- TEST_DATABASE_CHARSET = "UTF8"
- to file encoding and the database match. Before performing the test, Django will create a special auxiliary databases, so
- the user specified in settings.DATABASE_USER, must have
- the appropriate authority. To begin testing, type:
- python manage.py test news
- after which you will see something that shows
- 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
- 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
- adding previously in the main file the following URL-card
- lines:
- <source lang="python"> urlpatterns + = patterns ('django.contrib.auth.views',
- url (r '^ auth / password_reset /$',' password_reset'),
- ) </ Source>
- Here we include one of the built-in views, designed to recover your password. This is necessary since
- 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
- also can try password_reset in (Fig. 2).
- [[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-and POST-requests. As you know, for these purposes there
- special client: it emulates the query and returns the variables that are passed to the template for this URL. Add the
- tests.py file after line 10 the following code:
- <source lang="python" line="GESHI_NORMAL_LINE_NUMBERS" line start="11">
- >>> From django.contrib.auth.models import User
- >>> User = User.objects.create_user ('django_guru', 'user@example.com', 'password')
- >>> User.save ()
- >>> From django.test.client import Client
- >>> C = Client ()
- >>> C.login (username = 'django_guru', password = "password")
- True
- >>> Response = c.get ('/ news / 1 /')
- >>> Response.status_code
- 200
- >>> Print response.context [0] ['user']. Username
- django_guru
- >>> Response = c.post ('/ news / 1 /',{' username': "testuser", 'text':»»})
- >>> Response.status_code
- 200
- >>> Response = c.post ('/ news / 1 /',{' username': "testuser", 'text': »Comment text»})
- >>> Response.status_code
- 302
- >>> From news.models import Comment
- >>> Comment = Comment.objects.get (news = news)
- >>> Print comment.text
- Comment text </ source>
- See what is happening here. In lines 11-13 we create
- New User (django_guru), and in 14-15 - the test client. In
- line 16 django_guru authenticated, and now all of the system
- will be performed by 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
- (Line 19) - it should be 200, or test will fail.
- Then (lines 21-22), the reading of additional response data, we
- verify that the request is made a registered user
- django_guru. Now it's time to leave a comment - not in vain
- We logged in? Line 23 is generated POST-request (second
- argument to post () - dictionary data sent to the server).
- Note that the value of the key text is blank, and
- 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 (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 === ===
- What is a news site without the tape? RSS and / or Atom feeds are everywhere - will be
- 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">
- from feeds import LatestNews
- feeds = {
- 'Latest': LatestNews,
- }
- urlpatterns + = patterns ('',
- (R '^ feeds / (? P <url> .*)/$',' django.contrib.syndication.views.feed ',
- {'Feed_dict': feeds}),
- )
- </ Source>
- 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 as follows:
- <source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
- # -*- Coding: utf-8 -*-
- from django.contrib.syndication.feeds import Feed
- from news.models import News
- from django.contrib.syndication.feeds import FeedDoesNotExist
- class LatestNews (Feed):
- title = "Latest news from our site"
- description = "Recent developments on the site mysite.com"
- link = "http://127.0.0.1:8000/news/"
- def items (self):
- return News.objects.order_by ("-pub_date") [: 5]
- def item_link (self, obj):
- from django.core.urlresolvers import reverse
- return 'http://127.0.0.1:8000% s'% reverse ('news.news_detail', kwargs = {"news_id": obj.pk})
- </ Source>
- [[Image: LXF108 86 1.png | thumb | 250px | Fig. 3. Firefox offers to subscribe to our news website updated - now hold on!]]
- Fields title, description and link class LatestNews are required and are responsible for elements of the same name RSS. The method items ()
- passes the required objects in the tape, and item_link () is responsible for the link
- to the site. Now create a directory of feeds media / templates, and add
- in it two files, latest_description.html and latest_title.html: they will
- responsible for the news column form. In lates_description.html write:
- <nowiki> {{obj.description}} </ nowiki>
- and latest_title.html:
- <nowiki> [{{obj.pub_date | date: "dmY"}}] {{obj.title}} </ nowiki>
- Obj is a record of the sample, we
- return in line 13, file feeds / __init__.py. Having at
- http://127.0.0.1:8000/feeds/latest/, we shall offer Firefox
- save feed. Members KDE, is likely to prefer
- Akregator - with him, too, there is no problem (Fig. 3, 4)
- === === Understanding
- To make life easier for web-developer, Django has included a large
- number of representations to solve standard problems. For example, adding
- in the main file URL-mapping the following code:
- <source lang="python">
- from django.views.generic.list_detail import object_list
- from news.models import News
- urlpatterns + = patterns ('',
- ('^ Lastnews / $', object_list, {
- 'Queryset': News.objects.all (). Order_by ('-pub_date') [: 10]
- 'Template_name': 'news / last_news.html',
- 'Template_object_name': 'last_news'})
- ) </ Source>
- as well as replacing the file in news / templates / news / last_news.html
- {% For news in last_news%}
- on
- {% For news in last_news_list%}
- we will be able to view the latest news at
- 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,
- and replace it with
- "Last_news_list": news,
- As you may have guessed, the general idea object_list designed to work with a list of objects. Still there is a submission for
- O objects, depending on the date (django.views.generic.date_based .*), which makes it very easy to create backups of records:
- * Archive_index - withdrawal of the last object added to the database;
- * Archive_ {year, month, week, day, today} - the output of all the objects in a given year, month, week, day or today;
- * 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
- 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 in your settings.py. For example,
- We are now working the following processors:
- * Auth - information about the user: the object user, his rights of access and the messages that were sent to him;
- * I18n - information about the current language of the site and the client;
- * Request - information on request.
- Besides them, there is a processor debug, sending in
- pattern data of the executed SQL-queries, plus we can
- write your own! To do this we create in the root of our
- project directory and add the processors in it two files: __init__.py
- and context_processors.py. The latter should contain the following code:
- <source lang="python">
- import settings
- def site_settings (request):
- return {'SETTINGS': settings} </ source>
- To connect the processor, just list it in the tuple
- TEMPLATE_CONTEXT_PROCESSORS. We check availability:
- add a template news.html following:
- <nowiki> {{SETTINGS.TIME_ZONE}} </ nowiki>
- Of course, TIME_ZONE can be replaced by any other variable that is defined in settings.py.
- === === Sam himself filter
- 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
- project directory templatetags / and add the files __init__.py
- and filters.py. In filters.py write:
- <source lang="python" line="GESHI_NORMAL_LINE_NUMBERS">
- from django import template
- register = template.Library ()
- @ Register.filter
- def exp (value, arg):
- if value.isdigit () and arg.isdigit ():
- return int (value) ** int (arg)
- else:
- return '<span style="color:red"> Error </ span>'
- exp.is_safe = True </ source>
- 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
- filter in the system with the help of a decorator. Line 11 indicates
- that exp can return HTML-code. Because (for security), it automatically screened (<and> are replaced by < and
- > 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%}
- 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>
- Now test the filter by adding any template
- line.
- <nowiki> {{"4" | exp: "4"}} </ nowiki>
- At compile time, it will be replaced by 256. If we
- write
- <nowiki> {{"a" | exp: "4"}} </ nowiki>
- we see the word «Error», in red.
- 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>
- After registering a filter in the system, information about it becomes available at http://127.0.0.1:8000/admin/doc/filters/
- (Fig. 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
- as would be caused by representation, or if an error occurs, you can create your own components (middleware), or use
- 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, which lists the components involved in the project. We are:
- * 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 this session.
- * Django.contrib.auth.middleware.AuthenticationMiddleware And this - authorization.
- * Django.middleware.doc.XViewMiddleware used for automatic documentation Django.
- * Django.middleware.locale.LocaleMiddleware Internationalization.
- In addition to the above, the following are available in Django
- components (django.middleware .*):
- * Gzip.GZipMiddleware compression sends the page to save bandwidth.
- * Http.ConditionalGetMiddleware Support for conditional GET-requests to work with the Last-Modified and Etag.
- * Http.SetRemoteAddrFromForwardedFor reverse proxying.
- * Cache.CacheMiddleware The same cache, which we encountered in the previous lesson.
- * Transaction.TransactionMiddleware component for inclusion in SQL-queries of transaction structures: COMMIT, ROLLBACK.
- Note that not all databases support transactions.
- 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
- Class Python, having a number of methods called Django at some point in time. The first is the constructor
- __init__ (self), registering the components in the system. Next are the methods of determining the order of the code:
- * Process_request () - runs after the request, but before Django will look for the requested address in the URL-maps;
- * Process_view () - work out when the concrete representation is defined, but not yet started;
- * Process_response () - runs after the presentation.
- Used to compress the generated HTML.
- 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
- a book about Django - Django Book (http://www.djangobook.com); if you
- 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!
- {{Box | center |
- | Title =, etc., etc., other ...
- | Table of Contents = Over four lessons, we had to consider almost all possible
- Django, but something is left out ...
- *, E-mail
- Django offers a high-level API to send a message to
- one action:
- <source lang="python"> from django.core.mail import send_mail
- 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
- different content (HTML, text, graphics, etc.)
- *; CSV and PDF
- Django makes it easy to create data files, Comma Separated Values (CSV), as well as PDF-documents using
- 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, who helps organize paged:
- <source lang="python">>>> from django.core.paginator import Paginator
- >>> Objects = ['django', 'python', 'mysql', 'apache']
- >>> P = Paginator (objects, 2)
- >>> Page1 = p.page (1)
- >>> Page1.object_list
- ['Django', 'python'] </ source>
- Since most of our objects are stored in the database,
- 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
- machines? You need to create his map! Django will help
- here, and the function django.contrib.sitemaps.ping_google «cause»
- Google to update the index for your website.
- ; * Managing multiple sites
- 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%}
- you get at your disposal tag {% lorem%}, with
- which you can display certain Latin phrase «lorem
- ipsum ... »to fill the template" fish. "
- ; * And more
- Django has a lot of other "goodies" that are very
- well described in the accompanying documentation in English
- language.
- | Width =}}