<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Jaros&#322;aw Zabie&#322;&#322;o - BLOG: Category Python</title>
    <link>http://blog.zabiello.com/articles/category/python</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>moje notatki, linki, komentarze</description>
    <item>
      <title>Ruby 1.9 (YARV) vs. Python, Lua &amp;amp; PHP</title>
      <description>&lt;p&gt;Korzystaj&#261;c z tego, &#380;e &lt;a href="http://redhanded.hobix.com/cult/yarvIsRubyItIsItReallyIs.html"&gt;niedawno do repozytorium Rubiego zosta&#322; dodany &lt;span class="caps"&gt;YARV&lt;/span&gt;&lt;/a&gt; (wirtualna maszyna Rubiego)  pokusi&#322;em si&#281; o ma&#322;e por&#243;wnanie wydajno&#347;ci. Jako test u&#380;y&#322;em prostego programu jaki &lt;a href="http://groups.google.com/group/pl.comp.lang.python/browse_thread/thread/61095f8a08ca5f9e/1646948032dc08c0?lnk=st&amp;#38;q=&amp;#38;rnum=2&amp;#38;hl=pl#1646948032dc08c0"&gt;pojawi&#322; si&#281; na li&#347;cie pl.comp.lang.pyhon&lt;/a&gt; (musia&#322;em tylko troch&#281; zwi&#281;kszy&#263; p&#281;tle do 10 milion&#243;w iteracji, aby by&#322;y widoczne jakie&#347; wyniki) U&#380;yty sprz&#281;t: Athlon64 3700+, 64bit Ubuntu 6.0.6.&lt;/p&gt;


	&lt;p&gt;Sprawdzi&#322;em te&#380; z ciekawo&#347;ci &lt;span class="caps"&gt;PHP 5&lt;/span&gt;.2 na tym samym sprz&#281;cie. Dla tak prostego testu powinien m&#243;c da&#263; z siebie wszystko. Jest jednak wolniejszy od Rubiego 1.9.&lt;/p&gt;


	&lt;p&gt;Kod dla Pythona:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;
&lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;xrange&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;10000000&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
    &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Kod dla Lua:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;clock&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
&lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="number"&gt;10000000&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;+&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;clock&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Kod dla Rubiego:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt;
&lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;..&lt;/span&gt;&lt;span class="number"&gt;10_000_000&lt;/span&gt;
  &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;+&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Kod dla &lt;span class="caps"&gt;PHP&lt;/span&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_php "&gt;&amp;lt;?php
function microtime_float() {
 $time = microtime();
 return (double)substr($time, 11) + (double)substr($time, 0, 8);
}
$t =  microtime_float();
$a = 0;
for ($i = 0; $i &amp;lt; 10000000; $i++) {
  $a += $i;
}
print &amp;quot;$a\n&amp;quot;;
print  microtime_float()- $t;
?&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Wyniki:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Lua: 1.14 s&lt;/li&gt;
		&lt;li&gt;Ruby 1.9: &lt;strong&gt;1.49 s&lt;/strong&gt;&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;PHP 5&lt;/span&gt;.2: 1.74 s&lt;/li&gt;
		&lt;li&gt;Python 2.5: 2.64 s&lt;/li&gt;
		&lt;li&gt;Python 2.4.3: 2.72 s&lt;/li&gt;
		&lt;li&gt;Ruby 1.8.5: 3.83 s.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h2&gt;Drugie podej&#347;cie&lt;/h2&gt;


	&lt;p&gt;Tym razem wynik u&#347;redniam dla 10 pr&#243;b. Zwi&#281;kszy&#322;em ilo&#347;&#263; iteracji do &lt;strong&gt;20 mln&lt;/strong&gt;. No i&amp;#8230; Ruby 1.9 pobi&#322; wszystko. Zar&#243;wno Pythona jak i Lua! (PHP 5.2 po 30 sek. zg&#322;osi&#322; timeout. Musia&#322;em wi&#281;c u&#347;redni&#263; po 5 wynikach.)&lt;/p&gt;


	&lt;h3&gt;&lt;span class="caps"&gt;PYTHON&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;bench&lt;/span&gt;&lt;span class="punct"&gt;():&lt;/span&gt;
    &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
    &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;xrange&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;20000000&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
        &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;+=&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()-&lt;/span&gt;&lt;span class="ident"&gt;t&lt;/span&gt;
&lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;range&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
  &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;bench&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="number"&gt;10.0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;&lt;span class="caps"&gt;RUBY&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;bench&lt;/span&gt;
  &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt;
  &lt;span class="number"&gt;20_000_000&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;bench&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;&lt;span class="caps"&gt;LUA&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_lua "&gt;function bench()
  a = 0
  t = os.time()
  for i = 1, 20000000 do
    a = a + i
  end
  return os.time() - t
end
result = 0
for x = 1,10 do
  result = result + bench()
end
print(result/10)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_php "&gt;&amp;lt;?php
function bench() {
  $a = 0;
  $t =  time();
  for ($i = 0; $i &amp;lt; 20000000; $i++) $a += $i;
  return time() - $t;
}
$result = 0;
for ($x = 1; $x &amp;lt;= 5; $x++) $result += bench();
print $result / 5.0;
?&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Wyniki&lt;/h3&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;strong&gt;Ruby 1.9:       2.0953268 s.&lt;/strong&gt;&lt;/li&gt;
		&lt;li&gt;Lua 5.1:        2.4 s.&lt;/li&gt;
		&lt;li&gt;Python 2.5:     2.49481592178 s.&lt;/li&gt;
		&lt;li&gt;Python 2.4.3:   2.71687791348 s.&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;PHP 5&lt;/span&gt;.2:        4.2 s.&lt;/li&gt;
		&lt;li&gt;Ruby 1.8.5:     9.0153751 s.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Jestem ciekaw kiedy wyjdzie &lt;a href="http://i.loveruby.net/d/20060220.html#p10"&gt;Rails dostosowany do Ruby 1.9&lt;/a&gt;. Zapowiada si&#281; bardzo obiecuj&#261;co!&lt;/p&gt;</description>
      <pubDate>Mon, 01 Jan 2007 19:36:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:195b9e84-80ff-47b9-a2ae-38070f3da6f0</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2007/01/01/ruby19-yarv</link>
      <category>PHP</category>
      <category>Python</category>
      <category>Ruby</category>
      <category>lua</category>
      <category>python</category>
      <category>ruby</category>
      <category>php</category>
      <category>yarv</category>
      <category>benchmark</category>
    </item>
    <item>
      <title>Python 2.5 - mod_python, MySQLdb i PythonWin</title>
      <description>&lt;p&gt;W ko&#324;cu nie ma ju&#380; chyba powodu aby nie u&#380;ywa&#263; nowego Pythona 2.5 pod windowsami.  Od niedawna jest dost&#281;pna &lt;a href="http://apache.mirrors.esat.net/httpd/modpython/win/3.3.0b/"&gt;binarna instalka mod_pythona&lt;/a&gt; dla Apache 2.2. Jest te&#380; binarna &lt;a href="http://blog.zabiello.com/files/MySQL-python.exe-1.2.2b2.win32-py2.5.exe"&gt;instalka MySQLdb&lt;/a&gt;. Mimo &#380;e firma ActiveState co&#347; zasn&#281;&#322;a i &lt;a href="http://activestate.com/store/download.aspx?prdGUID=b08b04e0-6872-4d9d-a722-7a0c2dea2758"&gt;zatrzyma&#322;a si&#281; na razie na Pythonie 2.4.3&lt;/a&gt;, mo&#380;na sobie &#347;ci&#261;gn&#261;&#263; oddzielnie edytor &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=78018&amp;#38;package_id=79063&amp;#38;release_id=449591"&gt;PythonWin&lt;/a&gt;. Jest bardzo szybki i wygodny.&lt;/p&gt;</description>
      <pubDate>Tue, 26 Dec 2006 04:55:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:d4d8b22d-8581-46af-96a3-0f6f8002d961</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/12/26/python-2-5-mod_python-mysqldb-i-pythonwin</link>
      <category>Python</category>
      <category>python</category>
    </item>
    <item>
      <title>Skype3 i polski czat dla Rails&#243;w, Django i Pylonsa</title>
      <description>&lt;p&gt;Nowy Skype 3 wprowadza ma&#322;&#261; rewolucj&#281; w stos. do poprzedniej wersji. Mo&#380;na nie tylko rozmawia&#263;, ale pogra&#263; w szachy, k&#243;&#322;ko i krzy&#380;yk i inne gry (s&#261; b. &#322;adnie zrobione we Flashu 9). Mo&#380;na nagrywa&#263; rozmowy na dysk. Mo&#380;na tworzy&#263; publiczne czaty. I w&#322;a&#347;nie w tej sprawie pisz&#281; ten tekst bo 
stworzy&#322;em &lt;a href="http://www.skype.com/go/joinpublicchat?chat&amp;#38;skypename=hipertracker&amp;#38;topic=Rails%2C+Django%2C+Pylons+%28Polish%29&amp;#38;blob=qL-BIeEXX7A-qDj26JrmQcoze6L4kn_YE4016SUPrFY2DUmNoHxxVoeROiE4d1UZFQ4UJUo8-KPFDhFLqFhSVeo"&gt;polski czat dla mi&#322;o&#347;nik&#243;w framework&#243;w Ruby on Rails, Django i Pylons&lt;/a&gt;.
Wygodniej jest czasem skonsultowa&#263; co&#347; w czasie rzeczywistym ni&#380; na grupie czy &lt;a href="http://forum.rubyonrails.pl"&gt;forum dyskusyjnym&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Fri, 15 Dec 2006 00:48:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:6232652d-1ffd-4b4e-bcce-a630cc5bc711</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/12/15/skype3-i-polski-czat-dla-rails%C3%B3w-django-i-pylonsa</link>
      <category>Ruby on Rails</category>
      <category>Pylons</category>
      <category>Python</category>
      <category>Django (en)</category>
      <category>Ruby</category>
      <category>Django</category>
      <category>rails</category>
      <category>django</category>
      <category>pylons</category>
    </item>
    <item>
      <title>Subversion /etc/init.d script</title>
      <description>&lt;p&gt;Postanowi&#322;em troszk&#281; poprawi&#263; &lt;a href="http://blog.zabiello.com/articles/2006/10/05/ruby-svn-start"&gt;napisany wcze&#347;niej&lt;/a&gt; skrypt startowy do &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt;. Dorzuci&#322;em te&#380; wersj&#281; w Pythonie.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="constant"&gt;VERBOSE&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
&lt;span class="constant"&gt;USER&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;nobody&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="constant"&gt;APP&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/usr/bin/svnserve&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="constant"&gt;DIR&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/home/svn-repository&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="constant"&gt;PID&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/var/run/svnserve.pid&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;script&lt;/span&gt; &lt;span class="ident"&gt;action&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;start&lt;/span&gt;
    &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;exists?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;PID&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="ident"&gt;system&lt;/span&gt; &lt;span class="punct"&gt;%Q|&lt;/span&gt;&lt;span class="string"&gt;su -c &amp;quot;&lt;span class="expr"&gt;#{APP}&lt;/span&gt; -d -r &lt;span class="expr"&gt;#{DIR}&lt;/span&gt;&amp;quot; &lt;span class="expr"&gt;#{USER}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;system&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;echo `pidof -o %PPID &lt;span class="expr"&gt;#{APP}&lt;/span&gt;` &amp;gt; &lt;span class="expr"&gt;#{PID}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;stop&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;exists?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;PID&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;system&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/bin/kill -TERM &lt;span class="expr"&gt;#{File.read(PID)}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="ident"&gt;system&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/bin/rm -f &lt;span class="expr"&gt;#{PID}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="constant"&gt;true&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{APP}&lt;/span&gt; &lt;span class="expr"&gt;#{action}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="constant"&gt;VERBOSE&lt;/span&gt;
  &lt;span class="global"&gt;$defout&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;flush&lt;/span&gt; &lt;span class="comment"&gt;# unbuffered output&lt;/span&gt;
  &lt;span class="keyword"&gt;case&lt;/span&gt; &lt;span class="ident"&gt;action&lt;/span&gt;
    &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="symbol"&gt;:start&lt;/span&gt;
      &lt;span class="ident"&gt;start&lt;/span&gt;
    &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="symbol"&gt;:stop&lt;/span&gt;
      &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{File.basename(APP)}&lt;/span&gt; cannot be stopped because it cannot find &lt;span class="expr"&gt;#{PID}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="ident"&gt;stop&lt;/span&gt;
    &lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="symbol"&gt;:restart&lt;/span&gt;
      &lt;span class="ident"&gt;stop&lt;/span&gt;
      &lt;span class="ident"&gt;start&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="punct"&gt;%w{&lt;/span&gt;&lt;span class="string"&gt;start stop restart&lt;/span&gt;&lt;span class="punct"&gt;}.&lt;/span&gt;&lt;span class="ident"&gt;include?&lt;/span&gt; &lt;span class="constant"&gt;ARGV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;first&lt;/span&gt;
  &lt;span class="ident"&gt;script&lt;/span&gt; &lt;span class="constant"&gt;ARGV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;first&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_sym&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Usage: sudo &lt;span class="expr"&gt;#{__FILE__}&lt;/span&gt; {start|stop|restart}&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Ten sam skrypt w &lt;strong&gt;Pythonie&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;#!/usr/bin/env python&lt;/span&gt;

&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;

&lt;span class="constant"&gt;VERBOSE&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;True&lt;/span&gt;
&lt;span class="constant"&gt;USER&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;nobody&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="constant"&gt;APP&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/usr/bin/svnserve&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="constant"&gt;DIR&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/home/svn-repository&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="constant"&gt;PID&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/var/run/svnserve.pid&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;script&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;action&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;start&lt;/span&gt;&lt;span class="punct"&gt;():&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;exists&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;PID&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
      &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;system&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;su -c &amp;quot;%s -d -r %s&amp;quot; %s&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;%&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;APP&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;DIR&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;USER&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
      &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;system&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;echo `pidof -o %%PPID %s` &amp;gt; %s&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;%&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;APP&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;PID&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;stop&lt;/span&gt;&lt;span class="punct"&gt;():&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;exists&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;PID&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt; &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;False&lt;/span&gt;
    &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;system&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;/bin/kill -TERM %s&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;%&lt;/span&gt; &lt;span class="ident"&gt;file&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;PID&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;read&lt;/span&gt;&lt;span class="punct"&gt;())&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;True&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="constant"&gt;VERBOSE&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;%s %s&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;%&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;APP&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;action&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;action&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;start&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt;
    &lt;span class="ident"&gt;start&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
  &lt;span class="ident"&gt;elif&lt;/span&gt; &lt;span class="ident"&gt;action&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;stop&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; &lt;span class="ident"&gt;stop&lt;/span&gt;&lt;span class="punct"&gt;():&lt;/span&gt;
      &lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;%s cannot be stopped because it cannot find %s&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;%&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;path&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;basename&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;APP&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; &lt;span class="constant"&gt;PID&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;elif&lt;/span&gt; &lt;span class="ident"&gt;action&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;restart&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt;
    &lt;span class="ident"&gt;stop&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
    &lt;span class="ident"&gt;start&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;

&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;len&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;sys&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;argv&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="number"&gt;2&lt;/span&gt; &lt;span class="keyword"&gt;and&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;argv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;start&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;stop&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;restart&lt;/span&gt;&lt;span class="punct"&gt;'):&lt;/span&gt;
  &lt;span class="ident"&gt;script&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;sys&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;argv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
  &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="constant"&gt;VERBOSE&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;  &lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Usage: sudo %s {start|stop|restart}&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="punct"&gt;%&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;argv&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Sat, 07 Oct 2006 02:57:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:df9a9b43-95f9-453c-86a0-d8f3b55dd813</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/10/07/svn-start-script</link>
      <category>Python</category>
      <category>Ruby</category>
      <category>ruby</category>
      <category>python</category>
      <category>subversion</category>
    </item>
    <item>
      <title>IronPython 1.o</title>
      <description>&lt;p&gt;W dniu wczorajszym (5 wrze&#347;nia 2006) &#347;wiat&#322;o dzienne ujrza&#322;a &lt;a href="http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=IronPython&amp;#38;ReleaseId=423"&gt;wersja 1.0 projektu Iron Python&lt;/a&gt; &amp;#8211; implementacji j&#281;zyka &lt;a href="http://python.org"&gt;Python&lt;/a&gt; dzia&#322;aj&#261;cej na platformie .NET  i generuj&#261;cej kod 100% kompatybilny z &lt;span class="caps"&gt;CLR&lt;/span&gt; (Common Language Runtime).&lt;/p&gt;


	&lt;p&gt;Iron Python mo&#380;e by&#263; w zasadzie uwa&#380;any za produkt sygnowany przez Microsoft (pliki &lt;span class="caps"&gt;DLL&lt;/span&gt; s&#261; podpisane certyfikatem cyfrowym firmy Microsoft) i jako taki na pewno zyskuje sobie spore grono zwolennik&#243;w u&#380;ywaj&#261;cych go zar&#243;wno jako j&#281;zyka do tworzenia aplikacji jak i j&#281;zyka do osadzania w swoich w&#322;asnych aplikacjach.&lt;/p&gt;


	&lt;p&gt;Do uruchomienia IronPython&amp;#8217;a wymagany jest .NET Framework w wersji 2.0, gdy&#380; wykorzystuje on jej rozszerzenia, jak na przyk&#322;ad typy generyczne, czy metody dynamiczne. Deweloperzy otrzymuj&#261; do r&#281;ki, podobnie jak w standardowym Pythonie, interaktywn&#261; konsol&#281; z interpreterem j&#281;zyka, ale tak&#380;e mo&#380;liwo&#347;&#263; statycznej kompilacji do plik&#243;w wykonywalnych &amp;#8220;exe&amp;#8221;, czy bibliotek &amp;#8220;dll&amp;#8221;. Pomimo zgodno&#347;ci samego j&#281;zyka, obie implementacje jednak si&#281; r&#243;&#380;ni&#261;, jak cho&#263;by nieobecno&#347;ci&#261; wielu standardowych modu&#322;&#243;w. Szczeg&#243;&#322;owe informacje o r&#243;&#380;nicach mo&#380;na znale&#378;&#263; na &lt;a href="http://www.codeplex.com/IronPython"&gt;witrynie projektu&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Zobacz artyku&#322; &amp;#8220;&lt;a href="http://www.idg.pl/news/98134.html"&gt;Microsoft i dynamiczne j&#281;zyki&lt;/a&gt;&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Zobacz stron&#281;  &amp;#8220;&lt;a href="http://blogs.msdn.com/hugunin/archive/2006/09/05/741605.aspx"&gt;Jim Hugunin&amp;#8217;s Thinking Dynamic&lt;/a&gt; &amp;#8221; zawieraj&#261;c&#261; informacj&#281; autora IronPythona o wydaniu wersji 1.0.&lt;/p&gt;


	&lt;p&gt;Zobacz prezentacj&#281; wideo: &lt;a href="http://weblog.infoworld.com/udell/screenroom/ironpython_flv.html"&gt;The Screening Room. #8 August 2006: IronPython&lt;/a&gt; (dodane: 10 wrze&#347;nia 2006)&lt;/p&gt;</description>
      <pubDate>Wed, 06 Sep 2006 17:10:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:1974c396-f769-4950-802e-1ae653564f6f</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/09/06/ironpython-1-o</link>
      <category>Python</category>
      <category>python</category>
      <category>ironpython</category>
      <category>.net</category>
    </item>
    <item>
      <title>MySQLdb &amp;amp; client encoding</title>
      <description>&lt;p&gt;[vide: &lt;a href="http://blog.zabiello.com/pages/en/mysqldb-client-encoding"&gt;English version&lt;/a&gt;]&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://sourceforge.net/projects/mysql-python"&gt;MySQLdb&lt;/a&gt; to g&#322;&#243;wna biblioteka dla Pythona obs&#322;uguj&#261;ca baz&#281; MySQL. Baza ta (od werseji 4.1 wzwy&#380;) ma wbudowany wygodny mechanizm translacji znak&#243;w jakie maj&#261; by&#263; wy&#347;wietlane dla klienta. Oczywi&#347;cie, nale&#380;y za&#322;o&#380;y&#263;, &#380;e natywnym formatem danych dla bazy to &lt;span class="caps"&gt;UTF&lt;/span&gt;-8. Za pomoc&#261; prostej kwerendy (SET &lt;span class="caps"&gt;NAMES&lt;/span&gt; latin2) mo&#380;na wymusi&#263; aby wszelkie napisy by&#322;y wypluwane do klienta w wybranym formacie (tu: iso-8859-2).&lt;/p&gt;


	&lt;p&gt;Ostatnio, przy okazji pracy z &lt;a href="http://pylonshq.com"&gt;Pylons&lt;/a&gt;, przyjrza&#322;em si&#281; bardzo ciekawemu projektowi: &lt;a href="http://www.sqlalchemy.org/"&gt;SQLAlchemy&lt;/a&gt;. Wszystko wskazuje na to, &#380;e &lt;a href="http://www.sqlobject.org/"&gt;SQLObject&lt;/a&gt; odejdzie do lamusa (tym bardziej &#380;e jego tw&#243;rca co&#347; go porzuci&#322; i planuje stworzy&#263; nowy SQLObject2). &lt;a href="http://www.sqlalchemy.org/"&gt;SQLAlchemy&lt;/a&gt; jest nie tylko znacznie pote&#380;niejszym &lt;a href="http://en.wikipedia.org/wiki/Object-relationship_modeling"&gt;&lt;span class="caps"&gt;ORM&lt;/span&gt;&lt;/a&gt;, ale ma tak&#380;e znacznie lepsz&#261; dokumentacj&#281; ni&#380; SQLObject &amp;#8211; ok. 117 stron samego tylko &lt;a href="http://www.sqlalchemy.org/docs/"&gt;manuala&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Jedyny problem, jakie to typowe, to brak czytelnej opcji translacji polskich znak&#243;w. Podobny problem swego czasu znalaz&#322;em w Django (wys&#322;a&#322;em patcha i to poprawili dodaj&#261;c na sztywno &amp;#8220;SET &lt;span class="caps"&gt;NAMES&lt;/span&gt; utf8&amp;#8221;) W wypadku SQLAlchemy nie ma opcji do definicji kodowania po stronie klienta. Manual wspomina tylko o ustawieniu kodowania dla bazy, a to nie to samo. Okazuje, si&#281;, &#380;e rozwi&#261;zanie jest bardzo proste. Podczas tworzenia po&#322;&#261;czenia do bazy wystarczy u&#380;y&#263; dodatkowych parametr&#243;w. Nie ma potrzeby bawienia si&#281; w &#380;adne kwerendy &amp;#8220;SET &lt;span class="caps"&gt;NAMES&lt;/span&gt;&amp;#8221;. Owe parametry to &lt;strong&gt;use_unicode&lt;/strong&gt; i &lt;strong&gt;charset&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="constant"&gt;MySQLdb&lt;/span&gt;
&lt;span class="ident"&gt;conn&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;MySQLdb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connect&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;
    &lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;root&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; 
    &lt;span class="ident"&gt;passwd&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; 
    &lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; 
    &lt;span class="ident"&gt;use_unicode&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;False&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; 
    &lt;span class="ident"&gt;charset&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;cp1250&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;W powy&#380;szym wypadku, MySQL b&#281;dzie zak&#322;ada&#322; &#380;e klient ma odebra&#263; teksty w formacie string&#243;w cp1250. Za&#347; w wypadku u&#380;ycia &amp;#8220;use_unicode=True&amp;#8221; zwracane b&#281;d&#261; &#347;liczne obiekty unicodowe! Przyk&#322;adowy plik konfiguracyjny dla Pylonsa korzystaj&#261;cego z SQLAlchemy (config/&lt;i&gt;init&lt;/i&gt;.py) mo&#380;e zatem wygl&#261;da&#263; np. tak:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;sqlalchemy&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;
&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;sqlalchemy&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;pool&lt;/span&gt; &lt;span class="ident"&gt;as&lt;/span&gt; &lt;span class="ident"&gt;pool&lt;/span&gt;
&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="constant"&gt;MySQLdb&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;getconn&lt;/span&gt;&lt;span class="punct"&gt;():&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;MySQLdb&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connect&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;
        &lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;root&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; 
        &lt;span class="ident"&gt;passwd&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; 
        &lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; 
        &lt;span class="ident"&gt;use_unicode&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;False&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; 
        &lt;span class="ident"&gt;charset&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;utf8&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;

&lt;span class="ident"&gt;db&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;create_engine&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;
    &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;mysql://root:@localhost/test&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
    &lt;span class="ident"&gt;pool&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;pool&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;QueuePool&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;getconn&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;pool_size&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;20&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;max_overflow&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;40&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; 
    &lt;span class="ident"&gt;strategy&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;threadlocal&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="ident"&gt;metadata&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;BoundMetaData&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span class="ident"&gt;test_table&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Table&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;metadata&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;autoload&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;True&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Test(object):&lt;/span&gt;  
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;__str__&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;  
        &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;title&lt;/span&gt;  

&lt;span class="ident"&gt;test_mapper&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;mapper&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;Test&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;test_table&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;W powy&#380;szym przyk&#322;adzie, wymusi&#322;em kodowanie utf8 dla klienta oraz po&#322;&#261;czenie z baz&#261; dzia&#322;a&#263; b&#281;dzie w puli 20-40 w&#261;tk&#243;w. W&#322;a&#347;nie tego mi brakuje w Django: pracy wielow&#261;tkowej, bo zu&#380;ywa ona mniej pami&#281;ci. W/w model mo&#380;na u&#380;y&#263; w kontrolerze Pylons (controllers/home.py) np. tak:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;myproject&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;lib&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;base&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;
&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;myproject&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;models&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;HomeController(BaseController):&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;index&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;        
      &lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;rows&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;select&lt;/span&gt;&lt;span class="punct"&gt;([&lt;/span&gt;&lt;span class="ident"&gt;test_table&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;test_table&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;c&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;]).&lt;/span&gt;&lt;span class="ident"&gt;execute&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
      &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;render_response&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;/home.myt&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Wed, 16 Aug 2006 01:28:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:a7940b1d-4893-4e0a-b1aa-60d91a5a1207</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/08/16/mysqldb-client-encoding</link>
      <category>Databases</category>
      <category>Pylons</category>
      <category>Python</category>
      <category>mysql</category>
      <category>pylons</category>
      <category>python</category>
      <category>sqlalchemy</category>
    </item>
    <item>
      <title>PyQT 4</title>
      <description>&lt;p&gt;Firma Riverbank Computing &lt;a href="http://groups.google.com/group/comp.lang.python.announce/browse_thread/thread/3825f75b11877a80/a46233c0e98b539f?lnk=st&amp;#38;q=PyQT+group%3Acomp.lang.python.announce&amp;#38;rnum=1&amp;#38;hl=pl#a46233c0e98b539f"&gt;og&#322;osi&#322;a wypuszczenie PyQT4&lt;/a&gt;, pythonowego wrappera do biblioteki &lt;span class="caps"&gt;QT4&lt;/span&gt; firmy Trolltech. Wygl&#261;da to imponuj&#261;co: 8 g&#322;&#243;wnych modu&#322;&#243;w, 400 klas, 6 tys. metod i funkcji. Szczeg&#243;lnie dobre wra&#380;enie robi Designer (do budowania &lt;span class="caps"&gt;GUI&lt;/span&gt;) Assistamnt z naprawd&#281; &#322;adnie przygotowana dokumentacj&#261;. QT zawsze uchodzi&#322;a za bibliotek&#281; szybk&#261;, &#322;adn&#261; i dobrze napisan&#261;. Jedyny wcze&#347;niejszy problem wersj&#261; 3 dotyczy&#322; konieczno&#347;ci op&#322;at za u&#380;ytkowanie pod Windowsami. Jednak wersja 4.x jest ju&#380; w pe&#322;ni open source! Czy&#380;by rozpocz&#261;&#322; si&#281; na dobre proces wypierania &lt;a href="http://www.wxpython.org/"&gt;wxPythona&lt;/a&gt; i &lt;a href="http://www.pygtk.org/"&gt;PyGTK&lt;/a&gt;?&lt;/p&gt;</description>
      <pubDate>Tue, 13 Jun 2006 04:21:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:10ab28ef-599f-4f3f-b3c2-d13f36ae20ca</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/06/13/pyqt-4-01</link>
      <category>Python</category>
      <category>python</category>
      <category>qt</category>
    </item>
    <item>
      <title>Django - zab&#243;jcza aplikacja. Cz&#281;&#347;&#263; III.</title>
      <description>&lt;p&gt;W cz&#281;&#347;ci &lt;a href="http://blog.zabiello.com/articles/2006/05/27/django-wy%C5%BCszy-poziom-abstrakcji"&gt;pierwszej&lt;/a&gt;  i &lt;a href="http://blog.zabiello.com/articles/2006/05/27/django-zab%C3%B3jcza-aplikacja-cz%C4%99%C5%9B%C4%87-ii"&gt;drugiej&lt;/a&gt;  opisa&#322;em podstawowe zalety Pythona i &lt;a href="http://djangoproject.com"&gt;Django&lt;/a&gt;. Pora ma malutk&#261; demonstracj&#281; dzia&#322;aj&#261;cej aplikacji. B&#281;dzie to ma&#322;a, ale por&#281;czna wyszukiwarka biblijna (cho&#263; kod mo&#380;na &#322;atwo zaadoptowa&#263; do innych tre&#347;ci rzecz jasna). Jako baz&#281; u&#380;yj&#281; MySQL5. Zak&#322;adam tak&#380;e, &#380;e docelowo projekt b&#281;dzie chodzi&#322; pod Linuksem. Natomiast b&#281;dzie budowany i testowany pod Windowsami. Taki model pracy jest cz&#281;sto spotykany.  Django oczywi&#347;cie w wersji 0.95 &lt;span class="caps"&gt;SVN&lt;/span&gt;, czyli wersji pozbawionej wcze&#347;niejszej &amp;#8220;magii&amp;#8221; (kod Django jest teraz bardziej jawny i oparty na standardowych mechanizmach Pythona)&lt;/p&gt;


	&lt;h3&gt;Zaczynamy!&lt;/h3&gt;


	&lt;p&gt;Na pocz&#261;tku musimy stworzy&#263; projekt oraz aplikacj&#281; (Django w ramach jednego projektu potrafi obs&#322;ugiwa&#263; wiele aplikacji)&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;admin&lt;/span&gt;&lt;span class="punct"&gt;-&lt;/span&gt;&lt;span class="ident"&gt;django&lt;/span&gt; &lt;span class="ident"&gt;startptoject&lt;/span&gt; &lt;span class="ident"&gt;myproject&lt;/span&gt;
&lt;span class="ident"&gt;cd&lt;/span&gt; &lt;span class="ident"&gt;myproject&lt;/span&gt;
&lt;span class="ident"&gt;manage&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;py&lt;/span&gt; &lt;span class="ident"&gt;startapp&lt;/span&gt; &lt;span class="ident"&gt;biblia&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Zauwa&#380;my, &#380;e skrypt admin-django uruchamiamy tylko raz. Potem ju&#380; pos&#322;ugujemy si&#281; skryptem manage.py. Dzi&#281;ki temu odpada nam kombinowanie z definiowaniem zmiennej systemowej &lt;span class="caps"&gt;DJANGO&lt;/span&gt;_SETTINGS_MODULE. List&#281; wszystkich dost&#281;pny opcji, zar&#243;wno dla django-admin.py jak i manage.py, uzyskamy uruchamiaj&#261;c te skrypty bez &#380;adnego parametru.&lt;/p&gt;


	&lt;h3&gt;Wst&#281;pna konfiguracja.&lt;/h3&gt;


Mamy zatem stworzony katalog z projektem i aplikacj&#261;. Wpierw trzeba skonfigurowa&#263; plik settings.py&lt;sup&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;. Na pocz&#261;tku pliku ustawiamy:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;

&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;platform&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;win32&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt;
    &lt;span class="constant"&gt;DEBUG&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;True&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
    &lt;span class="constant"&gt;DEBUG&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;False&lt;/span&gt;
&lt;span class="constant"&gt;TEMPLATE_DEBUG&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;DEBUG&lt;/span&gt;

&lt;span class="constant"&gt;ADMINS&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;
    &lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;Administrator&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;twoj@email&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt;
    &lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span class="constant"&gt;MANAGERS&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;ADMINS&lt;/span&gt;

&lt;span class="constant"&gt;DATABASE_ENGINE&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;mysql&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="constant"&gt;DATABASE_NAME&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;myproject&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; 
&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;platform&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;win32&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt;
    &lt;span class="constant"&gt;DATABASE_USER&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;root&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
    &lt;span class="constant"&gt;DATABASE_PASSWORD&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
    &lt;span class="constant"&gt;DATABASE_USER&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;user_na_linuksie&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
    &lt;span class="constant"&gt;DATABASE_PASSWORD&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;haslo_pod_linuksem&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;platform&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;win32&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt;
    &lt;span class="constant"&gt;DATABASE_HOST&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="comment"&gt;# domyslnie bedzie localhost&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
    &lt;span class="comment"&gt;# pod linuksem zwykle korzystamy z szybkiego gniazda unix&lt;/span&gt;
    &lt;span class="constant"&gt;DATABASE_HOST&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;/var/run/mysqld/mysqld.sock&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="constant"&gt;DATABASE_PORT&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="comment"&gt;# czyli domy&#347;lnie b&#281;dzie 3306&lt;/span&gt;

&lt;span class="constant"&gt;ENABLE_PSYCO&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;False&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Kilka istotnych uwag.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Adres mailowy admina nie jest taki zupe&#322;nie nieistotny. W wypadku kiedy aplikacja na serwerze produkcyjnym si&#281; wy&#322;o&#380;y na jakim&#347; wyj&#261;tku, na ten adres jest automatycznie wysy&#322;any mail z wszystkimi szczeg&#243;&#322;ami. Trudno &#347;ledzi&#263;, czy w kt&#243;rym&#347; momencie aplikacja si&#281; nie wywali. Django zadba, aby &#380;aden taki wypadek nie umkn&#261;&#322; naszej uwadze&lt;sup&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Nale&#380;y sobie ustawi&#263; odpowiednie has&#322;a dost&#281;pu do MySQL5 pod windoz&#261; i pod linuksem.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Wa&#380;ne jest, aby wy&#322;&#261;czy&#263; obs&#322;ug&#281; akceleratora &lt;a href="http://psyco.sourceforge.net/"&gt;Psycho&lt;/a&gt;. To jeszcze nie jest dobrze przetestowane. Jak to mia&#322;em w&#322;&#261;czone, to pod Linuksem mia&#322;em problemy z dzia&#322;aniem djangowego panelu admina.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Musimy r&#281;cznie sobie stworzy&#263; (je&#347;li tego nie zrobili&#347;my) baz&#281;. Django za nas bazy nie stworzy. W naszym przypadku, tabelk&#281; na kt&#243;rej b&#281;dziemy pracowa&#263; mam ju&#380; gotow&#261; w bazie. Tu jest jej &lt;a href="http://zabiello.com/ftp/biblia_gdanska.zip"&gt;spakowany dump&lt;/a&gt; kt&#243;ry trzeba sobie za&#322;adowa&#263;.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Pozosta&#322;e ustawienia:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;LANGUAGE_CODE&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;pl&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="comment"&gt;# domy&#347;lnie by&#322; angielski&lt;/span&gt;
&lt;span class="comment"&gt;#... &lt;/span&gt;
&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;platform&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;win32&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt;
    &lt;span class="constant"&gt;MEDIA_ROOT&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;H:/home/myproject/biblia/public&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
    &lt;span class="constant"&gt;MEDIA_ROOT&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;/home/myproject/biblia/public&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="comment"&gt;#... &lt;/span&gt;
&lt;span class="constant"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;
    &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;django.contrib.auth&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
    &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;django.contrib.contenttypes&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
    &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;django.contrib.sessions&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
    &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;django.contrib.sites&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
    &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;myproject.biblia&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
&lt;span class="punct"&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Do s&#322;ownika &lt;span class="caps"&gt;INSTALLED&lt;/span&gt;_APPS musimy doda&#263; nasz&#261; aplikacj&#281; aby mo&#380;na by&#322;o jej u&#380;ywa&#263;. M&#243;wi o tym ostatnia linijka powy&#380;szego kodu. Zmienna &lt;span class="caps"&gt;MEDIA&lt;/span&gt;_ROOT musi by&#263; &lt;strong&gt;bezwzgl&#281;dn&#261; &#347;cie&#380;k&#261;&lt;/strong&gt; do plik&#243;w statycznych. Pod serwerem www odpowiada to zmiennej &lt;span class="caps"&gt;DOCUMENT&lt;/span&gt;_ROOT, czyli miejsca od kt&#243;rego serwer www cokolwiek widzi.&lt;/p&gt;


	&lt;h3&gt;Interaktywne testowanie Django z poziomu konsoli.&lt;/h3&gt;


W ka&#380;dej chwili mo&#380;emy odpali&#263; interaktywny dost&#281;p do &#347;rodowiska Django za pomoc&#261; komendy:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;manage&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;py&lt;/span&gt; &lt;span class="ident"&gt;shell&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
Warto sobie wcze&#347;niej zainstalowa&#263; &lt;a href="http://ipython.scipy.org/"&gt;ipythona&lt;/a&gt;, bo Django domy&#347;lnie pr&#243;buje uruchomi&#263; jego zamiast standardowy interpreter. Dzi&#281;ki ipythonowi mamy wspania&#322;e uzupe&#322;nianie metod do obiekt&#243;w + historia wczesniejszych operacji, kt&#243;ra nie znika wraz z zamkni&#281;ciem &lt;a href="http://ipython.scipy.org/"&gt;ipythona&lt;/a&gt;.

	&lt;h3&gt;Serwer.&lt;/h3&gt;


	&lt;p&gt;Mo&#380;emy odpali&#263; wbudowany serwer www za pomoc&#261; komendy:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;manage&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;py&lt;/span&gt; &lt;span class="ident"&gt;runserver&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Domy&#347;lnie serwer si&#281; podniesie pod adresem http://127.0.0.1:8000. Mo&#380;na zmieni&#263; zar&#243;wno port jak i adres jak kto&#347; chce, rzecz jasna. Odpal manage.py (bez parametr&#243;w) to si&#281; dowiesz, jak.&lt;/p&gt;


	&lt;h3&gt;&lt;span class="caps"&gt;ORM&lt;/span&gt;&lt;/h3&gt;


	&lt;p&gt;No dobrze, pora na co&#347; bardziej interesuj&#261;cego. Django operuje na relacyjnej bazie danych za pomoc&#261; swojego &lt;span class="caps"&gt;ORM&lt;/span&gt; (mapera relacyjno-obiektowego) Zalet takiego podej&#347;cia jest wiele. Wspomn&#281; tylko o tym, obiektowo mo&#380;na znacznie lepiej opisa&#263; dane modelu biznesowego ni&#380; to zrobi&#263; mo&#380;e czysty &lt;span class="caps"&gt;SQL&lt;/span&gt; ze swoimi kluczami obcymi i trigerami. Django wymaga aby w pliku myproject/biblia/models.py zdefiniowa&#263; dane dla &lt;span class="caps"&gt;ORM&lt;/span&gt;&amp;#8217;a. Zasada jest prosta: klasa odpowiada tabeli, a atrybuty klasy &amp;#8211; jej polom. Aby jednak sobie upro&#347;ci&#263; &#380;ycie, mo&#380;na pos&#322;u&#380;y&#263; si&#281; skryptem manage.py.&lt;/p&gt;


	&lt;p&gt;Poni&#380;szy skrypt robi &lt;strong&gt;introspekcj&#281; bazy&lt;/strong&gt; i wygeneruje pythonowe definicje wszystkich jej tabel. Jako parametr podajemy nazw&#281; naszej aplikacji (m&#243;wi&#322;em &#380;e Django jest zbudowane do pracy z wieloma aplikacjami w ramach projektu) Mo&#380;emy spokojnie zamaza&#263; plik models.py bo po stworzeniu projektu nic tam szczeg&#243;lnego nie ma.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="constant"&gt;H&lt;/span&gt;&lt;span class="punct"&gt;:\&lt;/span&gt;&lt;span class="ident"&gt;home\myproject&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;span class="ident"&gt;manage&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;py&lt;/span&gt; &lt;span class="ident"&gt;inspectdb&lt;/span&gt; &lt;span class="ident"&gt;biblia&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;biblia&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;models&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;py&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Mamy zatem nasz&#261; wst&#281;pn&#261; obiektow&#261; definicj&#281; dla nasej tabelki:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;db&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;models&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;BibliaGdanska(models.Model):&lt;/span&gt;
    &lt;span class="ident"&gt;id&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;models&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;IntegerField&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;primary_key&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;True&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;ref&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;models&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;CharField&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;unique&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;True&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;maxlength&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;9&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;chapter_nr&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;models&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;IntegerField&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;unique&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;True&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;verse_nr&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;models&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;IntegerField&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;unique&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;True&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;verse&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;models&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;TextField&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
    &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Meta:&lt;/span&gt;
        &lt;span class="ident"&gt;db_table&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;biblia_gdanska&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Mo&#380;e sprawd&#378;my, czy to dzia&#322;a za pomoc&#261; interaktywnej konsoli:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_python "&gt;H:\home\myproject&amp;gt;manage.py shell
Deleting alias &amp;lt;dir&amp;gt;, it's a Python keyword or builtin.
Python 2.4.3 (#69, Apr 11 2006, 15:32:42) [MSC v.1310 32 bit (Intel)]
Type &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.

IPython 0.7.1.fix1 -- An enhanced Interactive Python.
?       -&amp;gt; Introduction to IPython's features.
%magic  -&amp;gt; Information about IPython's 'magic' % functions.
help    -&amp;gt; Python's own help system.
object? -&amp;gt; Details about 'object'. ?object also works, ?? prints more.

In [1]: from myproject.biblia.models import BibliaGdanska
In [2]: BibliaGdanska.objects.count()
Out[2]: 31151L&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Bingo! Wida&#263;, &#380;e dzia&#322;a.&lt;/p&gt;


	&lt;h3&gt;Kontroler i szablon.&lt;/h3&gt;


	&lt;p&gt;Teraz pora na nasz&#261; aplikacj&#281; internetow&#261;. Musimy stworzy&#263; kontroler. Z tajemniczych powod&#243;w developerzy Django zamiast &lt;span class="caps"&gt;MVC&lt;/span&gt; (model-view-controller) stosuj&#261; nazw&#281; &lt;span class="caps"&gt;MTV&lt;/span&gt; (model-template-view). W ka&#380;dym razie, to co zwykle nazywamy kontrolerem oni nazywaj&#261; widokiem (view) a to co nazywamy widokiem, oni nazywaj&#261; szablonem. Mniejsza o nazwy. Kontroler  tworzymy w pliku myproject/biblia/views.py&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;#-*- coding: utf-8 -*-&lt;/span&gt;

&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;shortcuts&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;render_to_response&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;home&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;render_to_response&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;home.html&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Plik home.html jest szablonem. Stw&#243;rzmy na razie ten plik z napisem &amp;#8220;alama kota&amp;#8221; w &#347;rodku, aby zobaczy&#263;, czy to dzia&#322;a. Plik powinien le&#380;e&#263; w myproject/biblia/templates/home.html.&lt;/p&gt;


	&lt;h3&gt;Rozwi&#261;zywanie adres&#243;w &lt;span class="caps"&gt;URL&lt;/span&gt;&lt;/h3&gt;


	&lt;p&gt;Wpierw musimy powiedzie&#263; Django aby wiedzia&#322;, gdzie ma szuka&#263; naszego kontrolera. W tym celu dodajmy tak&#261; tre&#347;&#263; do pliku myproject/biblia/urls.py&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;conf&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;urls&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;defaults&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;
&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;settings&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="constant"&gt;DEBUG&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;MEDIA_ROOT&lt;/span&gt;

&lt;span class="ident"&gt;urlpatterns&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;patterns&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
    &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;include&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;myproject.biblia.urls&lt;/span&gt;&lt;span class="punct"&gt;')),&lt;/span&gt;
    &lt;span class="comment"&gt;#(r'^admin/', include('django.contrib.admin.urls')),&lt;/span&gt;
&lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="constant"&gt;DEBUG&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
    &lt;span class="ident"&gt;urlpatterns&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;patterns&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
        &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;^images/(?P&amp;lt;path&amp;gt;.*)$&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;django.views.static.serve&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;{'&lt;/span&gt;&lt;span class="string"&gt;document_root&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt; &lt;span class="constant"&gt;MEDIA_ROOT&lt;/span&gt;&lt;span class="punct"&gt;+'&lt;/span&gt;&lt;span class="string"&gt;/images&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;show_indexes&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt; &lt;span class="constant"&gt;True&lt;/span&gt;&lt;span class="punct"&gt;}),&lt;/span&gt;
        &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;^stylesheets/(?P&amp;lt;path&amp;gt;.*)$&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;django.views.static.serve&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;{'&lt;/span&gt;&lt;span class="string"&gt;document_root&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt; &lt;span class="constant"&gt;MEDIA_ROOT&lt;/span&gt;&lt;span class="punct"&gt;+'&lt;/span&gt;&lt;span class="string"&gt;/stylesheets&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;show_indexes&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt; &lt;span class="constant"&gt;True&lt;/span&gt;&lt;span class="punct"&gt;}),&lt;/span&gt;
        &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;^javascripts/(?P&amp;lt;path&amp;gt;.*)$&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;django.views.static.serve&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;{'&lt;/span&gt;&lt;span class="string"&gt;document_root&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt; &lt;span class="constant"&gt;MEDIA_ROOT&lt;/span&gt;&lt;span class="punct"&gt;+'&lt;/span&gt;&lt;span class="string"&gt;/javascripts&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;show_indexes&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt; &lt;span class="constant"&gt;True&lt;/span&gt;&lt;span class="punct"&gt;}),&lt;/span&gt;
    &lt;span class="punct"&gt;)&lt;/span&gt;    &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Powy&#380;szy kod robi kilka rzeczy.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Wi&#261;&#380;e domy&#347;ln&#261; stron&#281; z naszym projektem. Wej&#347;cie na http://127.0.0.1:8000/ przeka&#380;e sterowanie do pliku myproject/biblia/urls.py (kt&#243;ry za chwilk&#281; stworzymy).&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Takie podej&#347;cie powoduje &#380;e ka&#380;da aplikacja mo&#380;e posiada&#263; swoje niezale&#380;ne zasady rozwi&#261;zywania adresu url. Dlatego oddelegowujemy obs&#322;ug&#281; &lt;span class="caps"&gt;URL&lt;/span&gt;&amp;#8217;i do pliku urls.py wewn&#261;trz naszej aplikacji.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Zakomentowan&#261; linijk&#281; z panelem admina na razie zostawmy, wr&#243;c&#281; do tego p&#243;&#378;niej.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Ostatnie linijki s&#261; potrzebne do tego, aby Django obs&#322;ugiwa&#322; nie tylko plik Pythona ale tak&#380;e obrazki, style kaskadowe i skrypty j&#281;zyka JavaScript. Przyj&#261;&#322;em (wzoruj&#261;c si&#281; na &lt;a href="http://rubyonrails.com"&gt;Railsach&lt;/a&gt;) &#380;e s&#261; one odpowiednio w folderach myproject/biblia/public/images, myproject/biblia/public/stylesheets i myproject/biblia/public/javascripts.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Dlaczego ten kod jest dost&#281;pny tylko dla &lt;span class="caps"&gt;DEBUG&lt;/span&gt;=True? Ano dlatego, &#380;e do pracy developerskiej pod windoz&#261; nie potrzebujemy &#380;adnego Apache&amp;#8217;a ani Lighttpd. Wystarczy wbudowany serwer www jaki dostarcza Django. Natomiast na serwerze produkcyjnym, gdzie chcemy uzyska&#263; najwi&#281;ksz&#261; wydajno&#347;&#263;, lepiej aby te pliki podawa&#322; serwer www i Django si&#281; tego nie dotyka&#322;o. Tak b&#281;dzie najlepiej i najszybciej.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Pozosta&#322; do skonfigurowania plik myproject/biblia/urls.py&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;conf&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;urls&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;defaults&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;

&lt;span class="ident"&gt;urlpatterns&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;patterns&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;myproject.biblia.views&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
    &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;^$&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;home&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt;
   &lt;span class="comment"&gt;#(r'^admin/', include('django.contrib.admin.urls')),&lt;/span&gt;
&lt;span class="punct"&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Tu r&#243;wnie&#380; mamy zakomentowany panel admina. Zostawmy go na razie w spokoju. Mo&#380;na uruchamia&#263;: http://127.0.0.1:8000/ powinno wy&#347;wietli&#263; nasz szablon z tre&#347;ci&#261; &amp;#8220;ala ma kota&amp;#8221;. No to mo&#380;e lepiej aby wy&#347;wietli&#263; co&#347; bardziej atrakcyjnego. Zbudujmy formularz.&lt;/p&gt;


	&lt;h3&gt;Formularz&lt;/h3&gt;


	&lt;p&gt;Formularze s&#261; zmor&#261; wi&#281;kszo&#347;ci programist&#243;w. S&#261; upierdliwe w ob&#322;udze, walidacji i co gorsze, ci&#261;gle z nimi mamy do czynienia. Aby u&#322;atwi&#263; nam &#380;ycie, Django stosuje specjaln&#261; technik&#281; tzw. &lt;a href="http://www.djangoproject.com/documentation/forms/"&gt;manipulator&#243;w&lt;/a&gt;,  aby praca z formularzami by&#322;a mi&#322;a i przyjemna. Musz&#281; przyzna&#263;, &#380;e to by&#322;a jedna z wa&#380;niejszych rzeczy, jaka mnie przyci&#261;gn&#281;&#322;a do Django. &lt;a href="htttp://pylonshq.com"&gt;Pylons&lt;/a&gt; i &lt;a href="http://rubyonrails.com"&gt;Rails&lt;/a&gt; maj&#261; swoje &lt;a href="http://pylonshq.com/WebHelpers/module-webhelpers.rails.html"&gt;helpery&lt;/a&gt;, ale nie s&#261; one a&#380; tak wygodne jak to, co oferuje Django&lt;sup&gt;&lt;a href="#fn3"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;


	&lt;p&gt;Zobaczmy jak si&#281; u&#380;ywa manipulatora. Wpierw zmie&#324;my nasz szablon (plik: myproject/biblia/templates/home.html). B&#281;dzie to prosty formularz z jednym polem gdzie wpiszemy wyszukiwane s&#322;owo.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_html "&gt;&amp;lt;form method=&amp;quot;get&amp;quot; action=&amp;quot;&amp;quot;&amp;gt;

    {% if form.q.errors %} 
        &amp;lt;div class=&amp;quot;formError&amp;quot;&amp;gt;
          Wpisz fraz&#281; o d&#322;ugo&#347;ci min. 3 znak&#243;w.
        &amp;lt;/div&amp;gt;
    {% endif %}

    {{ form.q }}
    &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;szukaj&amp;quot; /&amp;gt;

&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Manipulator.&lt;/h3&gt;


	&lt;p&gt;Teraz pora na manipulator. Musimy stworzy&#263; plik myproject/biblia/manipulators.py o przyk&#322;adowej tre&#347;ci:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;re&lt;/span&gt;
&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;forms&lt;/span&gt;
&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;core&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;validators&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;SzukajManipulator(forms.Manipulator):&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;__init__&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
        &lt;span class="ident"&gt;regex&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;compile&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;(\w{3,})&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;U&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
        &lt;span class="ident"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;fields&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;
            &lt;span class="ident"&gt;forms&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;TextField&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;
                &lt;span class="ident"&gt;field_name&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;q&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
                &lt;span class="ident"&gt;length&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;30&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
                &lt;span class="ident"&gt;maxlength&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;255&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
                &lt;span class="ident"&gt;is_required&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="constant"&gt;True&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
                &lt;span class="ident"&gt;validator_list&lt;/span&gt;&lt;span class="punct"&gt;=[&lt;/span&gt;&lt;span class="ident"&gt;validators&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;MatchesRegularExpression&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;regex&lt;/span&gt;&lt;span class="punct"&gt;)]&lt;/span&gt;
                &lt;span class="punct"&gt;),&lt;/span&gt;
            &lt;span class="punct"&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Teraz zepnijmy wszystko razem w djangowym widoku (naszym kontrolerze). Zmie&#324;my tre&#347;&#263; pliku myproject/biblia/views.py na:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;#-*- coding: utf-8 -*-&lt;/span&gt;

&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;shortcuts&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;render_to_response&lt;/span&gt;
&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;forms&lt;/span&gt;
&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;manipulators&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="constant"&gt;SzukajManipulator&lt;/span&gt;
&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;models&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="constant"&gt;BibliaGdanska&lt;/span&gt;

&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;home&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
    &lt;span class="ident"&gt;recordset&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt;
    &lt;span class="ident"&gt;errors&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;_GET&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{}&lt;/span&gt;
    &lt;span class="ident"&gt;manipulator&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;SzukajManipulator&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
    &lt;span class="comment"&gt;# tworz&#281; kopi&#281; parametr&#243;w przekazanych z formularza&lt;/span&gt;
    &lt;span class="ident"&gt;_GET&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;GET&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;copy&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;GET&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
        &lt;span class="comment"&gt;# sprawdzam czy formularz nie ma b&#322;&#281;d&#243;w&lt;/span&gt;
        &lt;span class="ident"&gt;errors&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;manipulator&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;get_validation_errors&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;_GET&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
        &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; &lt;span class="ident"&gt;errors&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
            &lt;span class="ident"&gt;manipulator&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;do_html2python&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;_GET&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
           &lt;span class="comment"&gt;# wyszukuj&#281; cytaty &lt;/span&gt;
           &lt;span class="ident"&gt;recordset&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;BibliaGdanska&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;objects&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;all&lt;/span&gt;&lt;span class="punct"&gt;().&lt;/span&gt;&lt;span class="ident"&gt;filter&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;verse__icontains&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;_GET&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;q&lt;/span&gt;&lt;span class="punct"&gt;'])&lt;/span&gt;
    &lt;span class="ident"&gt;form&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;forms&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;FormWrapper&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;manipulator&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;_GET&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;errors&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;render_to_response&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;
        &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;home.html&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt;
        &lt;span class="punct"&gt;{'&lt;/span&gt;&lt;span class="string"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt; &lt;span class="ident"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
         &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;form&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt; &lt;span class="ident"&gt;form&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
         &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;recordset&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt; &lt;span class="ident"&gt;recordset&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;
         &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;hits&lt;/span&gt;&lt;span class="punct"&gt;':&lt;/span&gt; &lt;span class="ident"&gt;len&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;recordset&lt;/span&gt;&lt;span class="punct"&gt;)})&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Wy&#347;wietlenie wynik&#243;w.&lt;/h3&gt;


	&lt;p&gt;Aplikacja dzia&#322;a&lt;sup&gt;&lt;a href="#fn4"&gt;4&lt;/a&gt;&lt;/sup&gt;, ale nie wida&#263; wynik&#243;w. Wyniki wy&#347;wietlimy w  tym samym szablonie. Teraz b&#281;dzie wygl&#261;da&#322; tak:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_html "&gt;&amp;lt;form method=&amp;quot;get&amp;quot; action=&amp;quot;&amp;quot;&amp;gt;
    {% if form.q.errors %} 
        &amp;lt;div class=&amp;quot;formError&amp;quot;&amp;gt;
          Wpisz fraz&#281; o d&#322;ugo&#347;ci min. 3 znak&#243;w.
        &amp;lt;/div&amp;gt;
    {% endif %}    
    {{ form.q }}
    &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;szukaj&amp;quot; /&amp;gt;   
&amp;lt;/form&amp;gt;

{% if recordset %}
    &amp;lt;div&amp;gt;
      Znaleziono &amp;lt;b&amp;gt;{{ hits }}&amp;lt;/b&amp;gt; werset&#243;w:
    &amp;lt;/div&amp;gt;
    &amp;lt;ol&amp;gt;
    {% for row in recordset %}
        &amp;lt;li&amp;gt;
            {{ row.ref}} {{ row.chapter_nr}}:{{ row.verse_nr }} 
            &amp;amp;quot;{{ row.verse }}&amp;amp;quot;
        &amp;lt;/li&amp;gt;
    {% endfor %}
    &amp;lt;/ol&amp;gt;
{% else %}
    Nie znaleziono werset&#243;w dla frazy {{ request.GET.q }} :(
{% endif %}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Program powinien dzia&#322;a&#263;. Jednak w wypadku znalezienia mniej ni&#380; 5 werset&#243;w niezbyt po polsku zabrzmi wynik, np. &amp;#8220;Znaleziono 1 werset&#243;w&amp;#8221;. W wypadku j&#281;zyka angielskiego mo&#380;emy zmodyfikowa&#263; ten fragment szablonu za pomoc&#261; modyfikatora pluralize&lt;sup&gt;&lt;a href="#fn5"&gt;5&lt;/a&gt;&lt;/sup&gt;. Polski jezyk jest jednak znacznie bardziej wyrafinowany od angielskiego, bo u&#380;ywa 2 r&#243;&#380;nych form dla liczby mnogiej: 1 werset, 2 wersety, 5 werset&#243;w. Na szcz&#281;&#347;cie mo&#380;emy sobie zmieni&#263; spos&#243;b pracy tego modyfikatora.&lt;/p&gt;


	&lt;h3&gt;Przeci&#261;&#380;ene modyfikatora&lt;/h3&gt;


	&lt;p&gt;Aby nadpisa&#263; istniej&#261;cy modyfikator lub doda&#263; nowy, w&#322;asny, nale&#380;y stworzy&#263; wpierw folder myproject/biblia/templatetags z pustym plikiem o nazwie &lt;i&gt;init&lt;/i&gt;.py. Dodajemy tam drugi plik, o nazwie, powiedzmy: plugins.py o nast&#281;puj&#261;cej tre&#347;ci:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;sys&lt;/span&gt;
&lt;span class="ident"&gt;from&lt;/span&gt; &lt;span class="ident"&gt;django&lt;/span&gt; &lt;span class="ident"&gt;import&lt;/span&gt;  &lt;span class="ident"&gt;template&lt;/span&gt;

&lt;span class="ident"&gt;register&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;template&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;Library&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;

&lt;span class="attribute"&gt;@register&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;filter&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;pluralize&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;pluralize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Polish implementation&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="ident"&gt;try&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
        &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;int&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="number"&gt;4&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
            &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;y&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
        &lt;span class="ident"&gt;elif&lt;/span&gt; &lt;span class="ident"&gt;int&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
            &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;\xc3\xb3w&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="comment"&gt;# utf8&lt;/span&gt;
    &lt;span class="ident"&gt;except&lt;/span&gt; &lt;span class="constant"&gt;ValueError&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt; &lt;span class="comment"&gt;# invalid string that's not a number&lt;/span&gt;
        &lt;span class="ident"&gt;pass&lt;/span&gt;
    &lt;span class="ident"&gt;except&lt;/span&gt; &lt;span class="constant"&gt;TypeError&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
        &lt;span class="ident"&gt;try&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
            &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;int&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="number"&gt;4&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
                &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;y&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
            &lt;span class="ident"&gt;elif&lt;/span&gt; &lt;span class="ident"&gt;int&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="number"&gt;5&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;
                &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;\xc3\xb3w&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="comment"&gt;# utf8            &lt;/span&gt;
        &lt;span class="ident"&gt;except&lt;/span&gt; &lt;span class="constant"&gt;TypeError&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt; 
            &lt;span class="ident"&gt;pass&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Zamiast polskiego znaczka &#243;, u&#380;y&#322;em zapisu &amp;#8217;\xc3\xb3&amp;#8217; bo to warto&#347;&#263; utf-8 i taki zapis jest niezale&#380;ny od tego, w czym otworzymy plik. Nikt przypadkowo nie popsuje nam polskich ogonk&#243;w.&lt;/p&gt;


	&lt;p&gt;Aby to zadzia&#322;a&#322;o, musimy gdzie&#347; na pocz&#261;tku &lt;strong&gt;w szablonie&lt;/strong&gt; doda&#263; linijk&#281;, kt&#243;ra za&#322;aduje nam now&#261; definicj&#281; modyfikatora pluralize.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="punct"&gt;{%&lt;/span&gt; &lt;span class="ident"&gt;load&lt;/span&gt; &lt;span class="ident"&gt;plugins&lt;/span&gt; &lt;span class="punct"&gt;%}&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Kontekst i dziedziczenie szablon&#243;w.&lt;/h3&gt;


	&lt;p&gt;Nasz kod dzia&#322;a, ale kod &lt;span class="caps"&gt;HTML&lt;/span&gt; jest daleki od doskona&#322;o&#347;ci. Dobrze by&#322;oby dodac jaki&#347; nag&#322;&#243;wek, stopk&#281; itp. Django skopiowa&#322;o z pythonowych szablon&#243;w &lt;a href="http://cheetahtemplate.org/"&gt;Cheetah&lt;/a&gt; bardzo ciekawy spos&#243;b tworzenia kolejnych szablon&#243;w za pomoc&#261; obiektowego przeci&#261;&#380;ania starych.&lt;/p&gt;


	&lt;p&gt;Stw&#243;rzmy nasz szablon bazowy (myproject/biblia/templates/base.html)&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_html "&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot; 
&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&amp;gt;
&amp;lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot; xml:lang=&amp;quot;en&amp;quot; lang=&amp;quot;en&amp;quot;&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;Przyk&#322;ad aplikacji w Django&amp;lt;/title&amp;gt;
        &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;    
         &amp;lt;h3&amp;gt;Wyszukiwarka Biblii Gda&#324;skiej&amp;lt;/h3&amp;gt;
         &amp;lt;h4&amp;gt; (przyk&#322;ad aplikacji w Django)&amp;lt;/h4&amp;gt;
          &amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;
          {% block main %}
              tutaj b&#281;dzie jaka&#347; nowa tre&#347;&#263;   
          {% endblock %}
          &amp;lt;/div&amp;gt;
        &amp;lt;hr size=&amp;quot;1&amp;quot; /&amp;gt;
        &amp;lt;div&amp;gt;
        &amp;amp;copy; 2006 
        &amp;lt;a href=&amp;quot;http://blog.zabiello.com&amp;quot;&amp;gt;Jaros&#322;aw Zabie&#322;&#322;o&amp;lt;/a&amp;gt;. 
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Ostatecznie szablon home.html b&#281;dzie wi&#281;c wygl&#261;da&#322; tak:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_html "&gt;{% extends &amp;quot;base.html&amp;quot; %}

{% load plugins %}

{% block main %}

&amp;lt;form method=&amp;quot;get&amp;quot; action=&amp;quot;&amp;quot;&amp;gt;
    {% if form.q.errors %} 
        &amp;lt;p class=&amp;quot;formError&amp;quot;&amp;gt;Wpisz fraz&#281; o d&#322;ugo&#347;ci min. 3  &amp;quot;znak&#243;w&amp;quot;.&amp;lt;/p&amp;gt;
    {% endif %}    
    {{ form.q }}
    &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;szukaj&amp;quot; /&amp;gt;   
&amp;lt;/form&amp;gt;

{% if recordset %}
    &amp;lt;div&amp;gt;Znaleziono &amp;lt;b&amp;gt;{{ hits }}&amp;lt;/b&amp;gt; werset{{ hits|pluralize }}:&amp;lt;/div&amp;gt;
    &amp;lt;ol&amp;gt;
    {% for row in recordset %}
        &amp;lt;li&amp;gt;
            {{ row.ref}} {{ row.chapter_nr}}:{{ row.verse_nr }} 
            &amp;amp;quot;{{ row.verse }}&amp;amp;quot;
        &amp;lt;/li&amp;gt;
    {% endfor %}
    &amp;lt;/ol&amp;gt;
{% else %}
    &amp;lt;p&amp;gt;Nie znaleziono werset&#243;w dla frazy &amp;lt;b&amp;gt;{{ request.GET.q }}&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;
{% endif %}

{% endblock %}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Szablon oparty na innym szablonie implementuje dowolne bloki z poprzedniego. Ca&#322;y pozosta&#322;y kontekst jest automatycznie dziedziczony. Takie podej&#347;cie bardzo skraca wielko&#347;&#263; szablon&#243;w i czyni je jeszcze bardziej czytelnymi.&lt;/p&gt;


	&lt;h3&gt;Pod&#347;wietlanie szukanej frazy.&lt;/h3&gt;


	&lt;p&gt;Do pliku plugins.py gdzie wcze&#347;niej zmienili&#347;my definicj&#281; modyfikatora pluralize, dodajmy kolejny. B&#281;dzie nam pod&#347;wietla&#322; w wersetach to, co szukamy.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="attribute"&gt;@register&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;filter&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;highlight&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;highlight&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;q&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="keyword"&gt;not&lt;/span&gt; &lt;span class="ident"&gt;isinstance&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;unicode&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt; 
        &lt;span class="ident"&gt;s&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;unicode&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;utf-8&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
    &lt;span class="ident"&gt;s&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt; &lt;span class="ident"&gt;compile&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;(&lt;/span&gt;&lt;span class="punct"&gt;'+&lt;/span&gt;&lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;escape&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;q&lt;/span&gt;&lt;span class="punct"&gt;)+'&lt;/span&gt;&lt;span class="string"&gt;)&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;U&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;re&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;I&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;sub&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;r&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;strong class=&amp;quot;highlight&amp;quot;&amp;gt;\1&amp;lt;/strong&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;encode&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;utf-8&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;s&lt;/span&gt;    &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

W &#347;rodku zastosowano sztuczk&#281; z prze&#322;&#261;czeniem si&#281; na obiekty Unicode, aby mie&#263; pewno&#347;&#263; &#380;e polskie ogonki du&#380;e i ma&#322;e b&#281;d&#261; tak samo traktowane. W szablonie home.html wystarczy zmieni&#263; jedn&#261; linijk&#281;:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_html "&gt;{{ row.verse|highlight:request.GET.q }}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Co dalej?&lt;/h3&gt;


	&lt;p&gt;Mam nadziej&#281;, &#380;e artyku&#322; przybli&#380;y&#322; troch&#281; praktyczn&#261; stron&#281; uzywania Django. To dobry i szybki framework. Przyk&#322;adowe serwisy jakie w nim napisano s&#261; znacznie bardziej skomplikowane i wi&#281;ksze  ni&#380; te, co wida&#263; na stronie Rails. Django zosta&#322; napisany do szybkiego tworzenia ca&#322;kiem sporych serwis&#243;w&lt;/p&gt;


	&lt;p&gt;W kolejnym artykule, poka&#380;&#281; jak sobie wygodnie skonfigurowa&#263; panel admina kt&#243;ry udost&#281;pnia Django. Panel admina nie jest &#380;adnym prostym rusztowaniem (scaffolding) do modyfikacji bazy. To kompletna aplikacja dla u&#380;ytkownika ko&#324;cowego. Bardzo wygodna i &#322;atwa w u&#380;yciu. Panel Django jest kolejn&#261; z jego cech, kt&#243;ra daje mu wyra&#378;n&#261; przewag&#281; w stosunku do konkurencji.&lt;/p&gt;


	&lt;p&gt;&lt;del&gt;-&lt;/del&gt;&lt;/p&gt;


	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Kompletnie inaczej od 99% aplikacji pehapowych, gdzie o b&#322;&#281;dach dowiadujemy si&#281; najcz&#281;&#347;ciej dopiero wtedy, jak wszystko le&#380;y, albo jak kto&#347; &#322;askawie nas poinformuje.&lt;/p&gt;


	&lt;p id="fn2"&gt;&lt;sup&gt;2&lt;/sup&gt; Jak wida&#263;, to normalny plik Pythona. &#379;adne chore &lt;span class="caps"&gt;XML&lt;/span&gt; i inne formaty nie s&#261; w og&#243;le nam potrzebne &amp;#8211; Python jest wystarczaj&#261;co dobry, aby &#322;atwo i przyjemnie prezentowa&#263; zagnie&#380;d&#380;one struktury. Inne j&#281;zyki, jak np. Java nie zbyt dobrze nadaj&#261; si&#281; do takich rzeczy, dlatego musz&#261; posi&#322;kowa&#263; si&#281; &lt;span class="caps"&gt;XML&lt;/span&gt;.&lt;/p&gt;


	&lt;p id="fn3"&gt;&lt;sup&gt;3&lt;/sup&gt; Tzn. Railsy si&#281; ju&#380; poprawi&#322;y, bo jest plugin kt&#243;ry dodaje im tak&#261; sam&#261; funkcjonalno&#347;&#263; jak Django. Nazywa si&#281; active-form i mo&#380;na go zainstalowa&#263; prosto spod &lt;a href="http://www.radrails.org/"&gt;RadRails&amp;#8217;a&lt;/a&gt;.&lt;/p&gt;


	&lt;p id="fn4"&gt;&lt;sup&gt;4&lt;/sup&gt; Kto nie wierzy, niech sobie wpisze print recordset po operacji wyszukiwania. Na konsoli serwera www wy&#347;wietli mu si&#281; zawarto&#347;&#263; tej zmiennej.&lt;/p&gt;


	&lt;p id="fn5"&gt;&lt;sup&gt;5&lt;/sup&gt; Szablony Django korzystaj&#261; ze sk&#322;adni modyfikator&#243;w podobnych do pehapowych &lt;a href="http://smarty.php.net/manual/en/language.modifiers.php"&gt;Smart&#243;w&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Mon, 12 Jun 2006 22:29:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:9ca089fe-040f-4a11-9c20-a33482827899</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/06/12/django-zab%C3%B3jcza-aplikacja-cz%C4%99%C5%9B%C4%87-iii</link>
      <category>Python</category>
      <category>Django</category>
      <category>django</category>
    </item>
    <item>
      <title>Python 2.4 Quick Reference Card</title>
      <description>&lt;p&gt;Wysz&#322;a &#347;wietna, 18 stronicowa, &#347;ci&#261;ga do Pythona 2.4. Plik jest w formacie &lt;span class="caps"&gt;PDF&lt;/span&gt; i mo&#380;na pobra&#263; &lt;a href="http://www.limsi.fr/Individu/pointal/python/pqrc/versions/PQRC-2.4-A4-latest.pdf"&gt;st&#261;d&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 31 May 2006 10:53:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:b961cd55-386c-4cad-a078-914f0a4bc48e</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/05/31/python-2-4-quick-reference-card</link>
      <category>Python</category>
      <category>python</category>
    </item>
    <item>
      <title>Django - zab&#243;jcza aplikacja. Cz&#281;&#347;&#263; II.</title>
      <description>&lt;p&gt;Jak wspomnia&#322;em &lt;a href="http://blog.zabiello.com/articles/2006/05/27/django-wy%C5%BCszy-poziom-abstrakcji"&gt;w pierwszej cz&#281;&#347;ci&lt;/a&gt;, Django jest frameworkiem kt&#243;ry wyr&#243;s&#322; na bazie zastosowa&#324; komercyjnych. Zanim tw&#243;rcy zdecydowali si&#281; otworzy&#263; i udost&#281;pni&#263; jego kod na zasadach open-source, Django by&#322; ju&#380; wcze&#347;niej intensywnie u&#380;ywany w zastosowaniach komercyjnych&lt;sup&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;


	&lt;h2&gt;Przewaga Django&lt;/h2&gt;


	&lt;p&gt;Wcze&#347;niej pisa&#322;em o zaletach &lt;a href="http://blog.zabiello.com/articles/2006/03/04/pylons-czyli-si%C5%82a-myghty-i-wygoda-rubyonrails"&gt;Pylons&#243;w&lt;/a&gt;. Jednak&#380;e, po moich ostatnich testach z &amp;#8220;oczyszczon&#261; z magii&amp;#8221; wersj&#261; &lt;a href="http://djangoproject.com"&gt;Django&lt;/a&gt; musz&#281; przyzna&#263;, &#380;e jest to chyba aktualnie najlepszy framework, z jakim mia&#322;em do czynienia w tej klasie zastosowa&#324;.&lt;/p&gt;


	&lt;p&gt;Django oferuje &lt;strong&gt;znacznie wi&#281;cej&lt;/strong&gt; helper&#243;w i udogodnie&#324; ni&#380; &#347;wietny &lt;a href="http://pylonshq.com"&gt;Pylons&lt;/a&gt;. Poza wbudowan&#261; autoryzacj&#261; i zaawansowanym panelem admina, Django pracuje na wy&#380;szym poziomie abstrakcji ni&#380; Pylons czy Rails. Zamiast prostych generator&#243;w &lt;span class="caps"&gt;HTML&lt;/span&gt; dla formularzy, Django wprowadza kontrolki, kt&#243;re pracuj&#261; na wy&#380;szym poziomie abstrakcji. Bardzo przejrzy&#347;cie obs&#322;uguje tak&#380;e walidowanie formularzy. Kto si&#281; m&#281;czy&#322; z obs&#322;uga formularzy, nareszcie odetchnie z ulg&#261;. Idea &lt;a href="http://www.djangoproject.com/documentation/forms/"&gt;manipulator&#243;w&lt;/a&gt; bardzo upraszcza pisanie obs&#322;ugi formularzy. Kto&#347; powie, &#380;e to mo&#380;na sobie samemu napisa&#263;. Owszem. Ale Django daje ci to ju&#380; gotowe. Uruchamiasz i u&#380;ywasz zamiast traci&#263; czas.&lt;/p&gt;


	&lt;p&gt;Sprawa dokumentacji, i promocji w og&#243;lno&#347;ci, w wypadku wiekszo&#347;ci framework&#243;w Pythona jest po prostu &#380;enuj&#261;ca. Zdumiewaj&#261;ce jest jak to jest mo&#380;liwe, &#380;e nawet tak pot&#281;&#380;ne &#347;rodowisko jakim jest &lt;a href="http://zope.org"&gt;Zope&lt;/a&gt; ma tak s&#322;ab&#261; stron&#281; i chaotycznie porozrzucan&#261; dokumentacj&#281;.&lt;/p&gt;


	&lt;h3&gt;Kilka m&#261;drych posuni&#281;&#263;.&lt;/h3&gt;


	&lt;p&gt;Pierwsz&#261;, m&#261;dr&#261; rzecz&#261;, jak&#261; zrobiono po otwarciu kodu Django, by&#322;o skupienie si&#281; na pisaniu dokumentacji. Dzi&#281;ki temu, Django ma dzi&#347; jedn&#261; z najlepszych dokumentacji pomi&#281;dzy pythonowymi frameworkami. Bez dobrej dokumentacji, trudno aby ktokolwiek si&#281; zainteresowa&#322; projektem. 
Dokumentacja Django nie r&#243;wna si&#281; jeszcze temu co jest dost&#281;pne dla &lt;a href="http://rubyonrails.com"&gt;Rails&#243;w&lt;/a&gt; ale jest i tak lepsza od wi&#281;kszo&#347;ci framework&#243;w pythonowych.&lt;/p&gt;


	&lt;p&gt;Drugim, r&#243;wnie dobrym posuni&#281;ciem, by&#322; refaktoring pierwotnego kodu zgodnie z zasadami filozofii Pythona. Wg zasady, ze dzia&#322;anie jawne jest lepsze od domy&#347;lnego, nast&#261;pi&#322; proces &lt;strong&gt;usuwania &amp;#8220;magii&amp;#8221;&lt;/strong&gt; z kodu. Np. teraz zamiast tajemniczych prefiks&#243;w do nazw dodatkowych metod modelu, mo&#380;na tworzy&#263; je bardziej naturalnie &amp;#8211; jako metody klasowe Pythona. Aktualnie wersja pozbawiona &amp;#8220;magii&amp;#8221; jest dost&#281;pna w repozytorium &lt;span class="caps"&gt;SVN&lt;/span&gt;. Frameworkiem, kt&#243;ry jest mocno prze&#322;adowany &amp;#8220;magicznymi&amp;#8221; metodami jest Rails. Mo&#380;e to i &#322;adnie wygl&#261;da, ale filozofia Python pot&#281;pia takie podej&#347;cie, gdy&#380; to utrudnia programi&#347;cie w szybkim zorientowaniu si&#281; o co chodzi w kodzie.&lt;/p&gt;


	&lt;p&gt;Trzecim, dobrym pomys&#322;em, jest mo&#380;liwo&#347;ci &lt;strong&gt;testowania &#347;rodowiska w spos&#243;b interaktywny&lt;/strong&gt; w interpreterze. Domy&#347;lne uruchomia si&#281; to w miejscu stworzonego projektu za pomoc&#261; komendy:
&lt;em&gt;manage.py shell&lt;/em&gt;. Ta komenda odpala &lt;a href="http://ipython.scipy.org/"&gt;ipythona&lt;/a&gt; (ile mamy go zainstalowanego) i udost&#281;pnia w nim &#322;atwy dostep do ca&#322;ego &#347;rodowiska Django, jego modeli, bibliotek itp. Ipython to podrasowana wersja interpretera Pythona. &#346;wietnie uzupe&#322;nia metody, ma dobr&#261; histori&#281; edycji i ca&#322;y szereg dodatkowych mo&#380;liwo&#347;ci&lt;sup&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;


	&lt;p&gt;Przyk&#322;adem r&#243;&#380;nic w podej&#347;ciu do kwestii jawno&#347;ci i &amp;#8220;magii&amp;#8221; jest &lt;strong&gt;inny spos&#243;b podej&#347;cia do modu&#322;&#243;w i przestrzeni nazw mi&#281;dzy Pythonem a Ruby&lt;/strong&gt;. Python stosuje przejrzyst&#261; do b&#243;lu zasad&#281;: modu&#322; to po prostu plik. Wszystko co w nim jest, automatycznie jest &#322;adowane do przestrzeni nazw okre&#347;lonej nazw&#261; pliku. Python umo&#380;liwia tak&#380;e selektywne &#322;adowanie z modu&#322;u wybranych klas i metod. Wszystko jest niezmiernie czytelne.&lt;/p&gt;


	&lt;p&gt;W wypadku Rubiego mamy tylko wyra&#380;enie &lt;em&gt;require&lt;/em&gt; kt&#243;re odpala i w&#322;&#261;cza plik. Przy czym z tego kodu kompletnie nic nie mo&#380;na wywnioskowa&#263;, nawet tego, czy w &#347;rodku zawiera jakikolwiek modu&#322;. &lt;strong&gt;Trzeba zajrze&#263;&lt;/strong&gt; aby si&#281; dowiedzie&#263;, co zosta&#322;o dorzucone do naszej przestrzeni nazw. Pythonowa zasada &amp;#8220;jawno&#347;ci ponad domy&#347;laniem si&#281;&amp;#8221;, w tym wypadku stanowi kolejny argument na rzecz wi&#281;kszej produktywno&#347;ci Pythona wobec Rubiego.&lt;/p&gt;


	&lt;h3&gt;Django jest szybsze.&lt;/h3&gt;


	&lt;p&gt;Django jest cholernie szybkie. Nie tylko dlatego, &#380;e korzysta z Pythona i bytecodu, ale tak&#380;e dlatego, &#380;e jest dobrze napisane. Np. szablony Django s&#261; szybsze od &lt;a href="http://cheetahtemplate.org"&gt;Cheetah&lt;/a&gt; i nie wymagaj&#261; &#380;adnej dodatkowej kompilacji! Wszystkie wyra&#380;enia regularne u&#380;ywane np. do parsowania adres&#243;w &lt;span class="caps"&gt;URL&lt;/span&gt; s&#261; jednokrotnie kompilowane, s&#261; wi&#281;c wykonywane bardzo szybko. Ma&#322;o tego, w Django mo&#380;na w&#322;&#261;czy&#263; obs&#322;ug&#281; &lt;a href="http://psyco.sourceforge.net/"&gt;akceleratora Psyco&lt;/a&gt;. Wystarczy w mojprojekt/settings.py doda&#263; linijk&#281; &lt;em&gt;&lt;span class="caps"&gt;ENABLE&lt;/span&gt;_PSYCO = True&lt;/em&gt;. Railsy nie maj&#261; wydajno&#347;ciowo szans z Django. Chyba tylko &lt;a href="http://pylonshq.com"&gt;Pylons&lt;/a&gt; mo&#380;e si&#281; zbli&#380;y&#263; i nawi&#261;za&#263; jak&#261;&#347; walk&#281; na tym polu. Rails i &lt;span class="caps"&gt;PHP&lt;/span&gt; s&#261; tu bez szans.&lt;/p&gt;


	&lt;h3&gt;Django pracuje na wy&#380;szym poziomie abstrakcji.&lt;/h3&gt;


	&lt;p&gt;Obs&#322;uga formularzy, ich walidacja s&#261; zwykle uci&#261;&#380;liwe i programi&#347;ci maj&#261; z nimi ci&#261;gle do czynienia. &lt;a href="http://rubyonrails.com"&gt;Rails&lt;/a&gt; oraz  &lt;a href="http://pylonshq.com"&gt;Pylons&lt;/a&gt; (kt&#243;ry to skopiowa&#322; z Rails&#243;w) udost&#281;pniaj&#261; ca&#322;a grup&#281; wygodnych helper&#243;w do generowania kodu html np. do formularzy. Mimo, &#380;e to jest na pewno lepsze podej&#347;cie od bezpo&#347;redniego d&#322;ubania w kodzie &lt;span class="caps"&gt;HTML&lt;/span&gt;, to Django oferuje co&#347; znacznie lepszego &amp;#8211; &lt;strong&gt;kontrolki&lt;/strong&gt;. Co&#347;, co u&#380;ywa np. &lt;span class="caps"&gt;ASP&lt;/span&gt;.NET, tylko &#380;e znacznie prostsze w obs&#322;udze.&lt;/p&gt;


	&lt;p&gt;Djangowe modele korzystaj&#261;ce z mapowania relacyjno-obiektowego (ORM) r&#243;wnie&#380; pracuj&#261; &lt;a href="http://www.djangoproject.com/documentation/model_api/"&gt;na wy&#380;szym poziomie abstrakcji ni&#380; tylko odwzorowania prostych typ&#243;w&lt;/a&gt; danych jakie posiada relacyjna baza danych. Uwa&#380;am te&#380;, &#380;e djangowy &lt;span class="caps"&gt;ORM&lt;/span&gt; jest lepszy od &lt;a href="http://www.sqlobject.org/"&gt;SQLObject&lt;/a&gt;. Nie do&#347;&#263; &#380;e ma znacznie lepsz&#261; dokumentacj&#281;, to na dodatek ma wi&#281;cej mo&#380;liwo&#347;ci. Np. niby taka trywialna sprawa, ale jak w SQLObject odwzorowa&#263; takie zapytanie (z takim samym traktowaniem du&#380;ych i ma&#322;ych polskich znak&#243;w)?&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_sql "&gt;SELECT * FROM tabelka WHERE pole LIKE '%warto&#347;&#263;%'&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;W Django to jest trywialna operacja i na dodatek operuje na generatorze:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="constant"&gt;Tabelka&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;objects&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;filter&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;pole__icontains&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;warto&#347;&#263;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;):&lt;/span&gt;
    &lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;pole&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;W kolejnych cz&#281;&#347;ciach, zajm&#281; si&#281; przyk&#322;adem stworzenia prostej aplikacji internetowej. Poka&#380;&#281; te&#380; jak przeci&#261;&#380;y&#263; modyfikator &lt;a href="http://www.djangoproject.com/documentation/templates/#pluralize"&gt;pluralize&lt;/a&gt; aby uwzgl&#281;dnia&#322; polskie znaki, i jak obs&#322;ugiwa&#263; formularze (w&#322;&#261;cznie z dynamicznym budowaniem ich tre&#347;ci)&lt;/p&gt;


	&lt;p&gt;&lt;del&gt;-&lt;/del&gt;&lt;/p&gt;


	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; Poza ca&#322;ym &lt;a href="http://code.djangoproject.com/wiki/DjangoPoweredSites"&gt;szeregiem z&#322;o&#380;onych portali&lt;/a&gt;, developerzy Django sprzedaj&#261; &lt;a href="http://www.ellingtoncms.com/"&gt;Elington&lt;/a&gt; &amp;#8211; profesjonalny &lt;span class="caps"&gt;CMS&lt;/span&gt; zbudowany na bazie tego frameworku. Oczywi&#347;cie &lt;a href="http://rubyonrails.com"&gt;Railsy&lt;/a&gt; r&#243;wnie&#380; powsta&#322;y pierwotnie jako projekt do zastosowa&#324; komercyjnych. St&#261;d nic dziwnego, &#380;e oba &#347;rodowiska oferuj&#261; sporo interesuj&#261;cych rozwi&#261;za&#324;.&lt;/p&gt;


	&lt;p id="fn2"&gt;&lt;sup&gt;2&lt;/sup&gt; Aby dzia&#322;a&#322;y uzupe&#322;niania metod (po wci&#347;ni&#281;ciu klawisza Tab) trzeba doinstalowa&#263; modu&#322; &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=82407&amp;#38;package_id=84552"&gt;readline&lt;/a&gt; oraz &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=71702&amp;#38;package_id=71318"&gt;ctypes&lt;/a&gt;. Je&#347;li interpreter nie wyrzuca wyj&#261;tku po  wpisaniu &lt;em&gt;import readline&lt;/em&gt;, to znaczy &#380;e mamy go ju&#380; zainstalowanego.&lt;/p&gt;


&lt;p style="text-align:center;"&gt;(Zobacz: &lt;a href="http://blog.zabiello.com/articles/2006/06/12/django-zab%C3%B3jcza-aplikacja-cz%C4%99%C5%9B%C4%87-iii"&gt;cz&#281;&#347;&#263; &lt;span class="caps"&gt;III&lt;/span&gt;&lt;/a&gt;)&lt;/p&gt;</description>
      <pubDate>Sat, 27 May 2006 18:53:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:554ba58d-ef92-4c15-ace3-deffeb48adb7</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/05/27/django-zab%C3%B3jcza-aplikacja-cz%C4%99%C5%9B%C4%87-ii</link>
      <category>Python</category>
      <category>Django</category>
      <category>django</category>
    </item>
  </channel>
</rss>
