Ładowanie Ładowanie

Artykuł > Django – framework dla zapracowanych programistów. Wprowadzenie

strony: 1 | 2 | 3 | 4 | ... | 5 następna »
wydrukuj: print publikuj: wykop dodaj do flakera Dodaj jako nius na OSnews.pl! delicious

Django – framework dla zapracowanych programistów. Wprowadzenie

2009-05-11 09:07:00 | Rafał Jońca
Django – framework dla zapracowanych programistów. Wprowadzenie

Przy coraz krótszych terminach realizacji projektów i coraz większej ich złożoności, deweloperzy aplikacji sieciowych potrzebują systemów, które zapewnią sprawną realizację celów. Bazujący na Pythonie Django jest właśnie jednym z takich rozwiązań. Spośród innych frameworków wyróżniają go: przejrzysty schemat danych, precyzyjne dopasowanie komponentów standardowych i łatwość ich rozbudowy, a także bogata dokumentacja oraz wygodny system administracyjny. Jeśli więc w trakcie procesu projektowania zdarza się nam przekraczać kolejne terminy, a zamiast podążać prostą drogą do celu grzęźniemy w tworzeniu standardowych rozwiązań, warto przyjrzeć się bliżej metodom pracy z Django. Rozwiązanie wszystkich naszych problemów może być bowiem bardzo blisko.


Spis treści

Historia
Elastyczny wzorzec MVC, czyli MTV
Nie wymyślaj koła na nowo!
Przejrzysta struktura projektu
Przykładowe style pracy z Django
Aplikacje wbudowane
Aplikacje zewnętrzne
Wdrożenie i konfiguracja
Podsumowanie

Django w wielu materiałach wymieniany jest obok najpopularniejszego w ostatnich latach frameworka – Ruby on Rails. Choć różni je język (Django – Python, Rails – Ruby), podejście do niektórych zagadnień i sposób rozbudowy, to na podstawowym poziomie oba programy starają się wypełnić to samo zadanie – dać deweloperowi narzędzie elastyczne, wygodne, szybkie i łatwe do opanowania.

Django bazuje na Pythonie – języku ogólnego stosowania, który istnieje tak długo jak Java i jest bardziej elastyczny niż PHP. To właśnie tej podstawie zawdzięcza framework przejrzystość i prostotę, pozwalającą generować kod krótki i łatwy do późniejszej analizy. Co równie istotne, Python doczekał się wielu bibliotek dodatkowych związanych nie tylko z Internetem, ale także innymi działami informatyki – obliczeniami matematycznymi czy grafiką komputerową. Znacznemu skróceniu ulega dzięki temu czas tworzenia nietypowych aplikacji – wystarczy dobrze poszukać, by stwierdzić, że rozwiązaniem naszego problemu może być stworzona już wcześniej biblioteka.

Opisując zalety tandemu tandem Python-Django, warto także wspomnieć, że stał on się standardową platformą w systemie Google App Engine, pozwalającym na tworzenie witryn internetowych bazujących na infrastrukturze Google. W Polsce Django docenił między innymi serwis społecznościowy Grono.net oraz gazeta Super Express.


Historia

Framework Django narodził się w 2003 roku w USA, gdy w internetowym dziale jednej z lokalnych gazet programiści stwierdzili, że chcą przenieść istniejące, napisane w PHP witryny na platformę języka Python. Dostępne w tym czasie frameworki, były dla nich albo zbyt rozbudowane (Zope), albo nie spełniały specyficznych potrzeb serwisu. Ponieważ dziennikarstwo to dziedzina wymagająca natychmiastowej reakcji na zmieniające się wydarzenia, nowy system musiał zapewniać tworzenie kolejnych elementów składowych nie w tygodnie czy miesiące, ale w dni i godziny. Od pomysłu do realizacji i udostępnienia użytkownikom nowego działu mijał bowiem częstokroć tylko jeden dzień.

Django nie powstawało więc jako niezależny framework – między 2003 a 2005 rokiem stanowiło część większego systemu trzech portali. Dzięki temu jego użytkownicy także obecnie mogą mieć pewność, że wszystkie proponowane rozwiązania sprawdziły się w praktyce i to w bardzo wymagającym środowisku. W 2005 roku nastąpiło wyodrębnienie rdzenia systemu i udostępnienie go na zasadach Open Source pod nazwą Django. Przez kolejne trzy lata system ulegał metamorfozie i wielu udoskonaleniom, by w 2008 roku osiągnąć status 1.0. Obecnie najnowszą wersją jest wydanie 1.1.


Elastyczny wzorzec MVC, czyli MTV

W trakcie projektowania zrębów prostej aplikacji internetowej, najczęściej nie przejmujemy się faktem, że w tym samym pliku mieszają się ze sobą dane, logika biznesowa, logika prezentacji i kod HTML. Kiedy program zaczyna się rozrastać, taki zlepek utrudnia nie tylko dalszą rozbudowę, ale także wielokrotne wykorzystanie podobnych fragmentów kodu.

Pomoc w rozwiązaniu przedstawionego problemu zapewnia podział aplikacji na logiczne elementy – nazywany skrótowo wzorcem MVC (Model-View-Controller). Ponieważ skrót MVC nie brzmiał zbyt chwytliwie, autorzy Django użyli „odmiany” o nazwie MTV (Model-Template-View). Różnice między wzorcami dotyczą z pozoru tylko szczegółów, te drobne modyfikacje mogą jednak stanowić o elastyczności całego systemu. Niezależnie jednak od nazwy, zastosowanie separacji poszczególnych warstw aplikacji ułatwia wielokrotne wykorzystanie podobnych elementów (zasada DRY), zmniejsza złożoność i upraszcza poszukiwanie kodu realizującego daną funkcjonalność (zasada KISS).

MVC, MTV, DRY i KISS, czyli...

  • MVC (Model-View-Controller) to skrót od model-widok-kontroler, natomiast MTV (Model-Template-View) to skrót od model-szablon-widok. W obu wypadkach model oznacza dokładnie to samo. Widok w schemacie MVC odpowiada za prezentację danych – w MTV tę rolę pełni szablon. Dla MVC kontroler to klasa z metodami zawierająca logikę aplikacji, natomiast w MTV rolę tę pełnią widoki będące zwykłymi funkcjami.
  • DRY (Don't Repeat Yourself) to zasada zachęcająca do unikania wielokrotnego pisania tego samego (podobnego) kodu lub też stosowania metody kopiuj-wklej.
  • KISS (Keep It Simple, Stupid) oznacza dążenie do tworzenia rozwiązań, które są proste, przejrzyste i zrozumiałe.

Warto przyjrzeć się bliżej, jak Django wciela w życie opisane wyżej zasady. Pierwszy komponent – modele – to klasy definiowane w języku Python, określające w czytelny sposób strukturę tabel, na podstawie której Django automatycznie generuje zapytania SQL. Te ostatnie dotyczą między innymi tworzenia samych tabel, ich edycji oraz pobierania danych. W wielu sytuacjach nie trzeba zatem w ogóle używać języka SQL, co zapewnia lepszą kompatybilność kodu (obsługę wielu systemów bazodanowych) i sprzyja zachowaniu zasady DRY.

Widoki są z kolei standardowymi funkcjami Pythona, których jedynym zadaniem jest pobieranie obiektu żądania i zwracanie obiektu odpowiedzi lub zgłaszanie wyjątku. Nie musimy więc tworzyć specjalnych klas kontrolerów (jak w modelu MVC), zastanawiać się, co ze sobą połączyć i po jakich klasach bazowych dziedziczyć. Takie podejście sprzyja więc bezpośrednio realizacji zasady KISS. Warto w tym miejscu zaznaczyć, że jeśli zajdzie potrzeba, możemy oczywiście tworzyć także odpowiednie klasy kontrolerów.

Ostatnim elementem opisanej struktury są szablony służące do generowania końcowych wyników. Zbudowano je według możliwie uproszczonego, niebazującego na języku XML schematu. Dzięki temu cała struktura jest zrozumiała zarówno dla projektantów jak i grafików oraz innych osób standardowo niezajmujących się programowaniem (zasada KISS). Jednocześnie obsługuje ona system dziedziczenia przypominający dziedziczenie klas, co minimalizuje powtórzenia kodu HTML i pomaga zastosować się do wskazówki wyrażonej akronimem DRY.

Najnowsze wiadomości
1 | 2 | 3 | 4 | ... | 5 następna »

reklama

strony: 1 | 2 | 3 | 4 | ... | 5 następna »
wydrukuj: print publikuj: wykop dodaj do flakera Dodaj jako nius na OSnews.pl! delicious

Czytaj webhosting.pl:

Dyskusja

dodaj komentarz
+1 + -
comnt #01 pats 2009-05-11 10:47:22
pats Bardzo dobry artykuł, naprawdę bomba. Nie wnikam za bardzo w szczegóły, bo pare elementów można by opisać lepiej, ale ogólnie - pierwsza klasa. 

Składam niniejszy pokłony dla redaktora ;)
------------------
Browser: Opera/9.64 (Windows NT 5.1; U; pl) Presto/2.1.1
0 + -
comnt #02 gość 2009-05-11 12:20:03
gość Chcemy więcej artykułów o Pythonie :)
------------------
Browser: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.10) Gecko/2009042523 Ubuntu/8.10 (intrepid) Firefox/3.0.10
0 + -
comnt #03 snf 2009-05-11 12:21:25
snf przydała by sie opcja: zapisz jako pdf, niezły wstęp dla początkujacych.
------------------
Browser: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl; rv:1.9.1b4) Gecko/20090423 Firefox/3.5b4
0 + -
comnt #04 Secator 2009-05-11 13:28:45
Secator Python Python!! FTW! Precz z rubinami i perłami w programowaniu!
------------------
Browser: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10
0 + -
comnt #05 -ja- 2009-05-11 13:47:44
-ja- oj dzieci... tak się podniecacie tym językiem, tamtym językiem... a tak naprawdę liczy się architektura całości, projekt bazy i pełno innych rzeczy, które nie mają nic wspólnego z językiem. A jak ktoś twierdzi że jest inaczej, to poproszę o jakieś argumenty. Ciągle porównuje się np. Pythona czy Rubiego z PHP... ale jedyne co słyszę, że PHP jest do dupy bo tak jest i już... albo że nie ma klas, albo że nie ma tego czy tamtego... chociaż ma i model obiektowy z PHP nie jest gorszy od Pythonowego (gdzie np. nie ma w ogóle w klasach zmiennych prywatnych czy chronionych).

Jak już ktoś tak uwielbia Pythona to niech napisze ładny artykuł o tym dlaczego Python jest taki zaje i jest lepszy... ale z sensownymi argumentami poproszę.
------------------
Browser: Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10
0 + -
comnt #06 dAREuS® 2009-05-11 14:07:57
dAREuS @-ja-: trochę uprościłeś sprawę, my naprzykład widzimy wszelkie "za" i "przeciw". Zobacz ten artykuł.
------------------
dAREuS

Browser: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)
0 + -
comnt #07 Jan Koprowski® 2009-05-11 19:19:06
jankoprowski Brawo ! Genialna forma i świetna przyjemna treść :]
------------------
Jan Koprowski

Browser: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/530.8 (KHTML, like Gecko) Chrome/2.0.177.1 Safari/530.8
0 + -
comnt #08 pako® 2009-05-12 20:13:39
pako Framework całkiem niezły, ale dla zastosowań mało skalowalnych.

ORM:

- nie ma możliwości połączenia się z wieloma bazami danych,

- nie ma podstawowych funkcji typu grupowanie czy sumowanie wartości z podanych kolumn,

-

bardziej złożone zapytania (czyli w praktyce w większym serwisie

często) i tak trzeba klepać czysty SQL, bo funkcjonalnie nie da się ich

zrobić przez ORMa,

Url dispacher: nie wiem jak dla

pozostałych, ale dla mnie używanie regexpów w dispacherze to nie jest

do końca to, czego bym sobie życzył w tego typu mechaniźmie. W praktyce

spotkałem się z tym tylko w Django.



Templates:

- przy tworzeniu własnych filtrów nie mamy dostępu do contextu,

- własne filtry mają również duże ograniczenia jeśli chodzi o przyjmowane argumenty,

-

porównanie (utf)2 z (int)2 daje wartość false, ale nie ma też

możliwości rzutowania typów w szablonach, nie można również załatwić

tego filtrem,



Generalnie Django jako framework nadaje się do pomniejszych projektów. Jeśli chodzi o skalowalność to zdecydowanie odradzam.
------------------
Browser: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009030814 Iceweasel/3.0.7 (Debian-3.0.7-1)
0 + -
comnt #09 -ja- 2009-05-13 10:31:35
-ja- @dAREuS®:

a ten link to gdzie miał prowadzić?
------------------
Browser: Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10
0 + -
comnt #10 Restless 2009-05-13 10:36:16
Restless @pako:

1. wiele baz danych - fakt, w "standardowy" sposób nie ma takiej możliwości, acz Django to Python i oczywiście można się podpinać z poziomu pythona do wielu baz danych

2. mówisz o tym: http://docs.djangoproject.com/en/dev/topics/db/aggregation/#topics-db-aggregation ?

3. orm jest calkiem niezly i jak dla mnie, a niejeden system w Django napisalem, w zdecydowanej wiekszości przypadków wystarcza.

4. url dispatcher i zastosowanie regexow jest tym czego bym sobie zyczyl w tego typu mechanizmie. Dla mnie to super sprawa. A jesli, jak napisales, inni tego nie stosuja to co z tego wynika? Jedzcie g... miliardy much nie mogą się mylić ;)

5. Co do filtrow to nie mają contextu bo nie mają mieć. Moje auto nie lata bo nie mialo nigdy latać, za to bardzo dobrze jeździ.

6. a jakie to bardzo duże ograniczenia mają filtry?

7. nie rozumiem czemu porownanie utf z int mialoby dawac true, jakos niejasno ten punkt napisales



Generalnie Django jako framework nadaje się do różnego rodzaju projektów, zarówno małych jak i tych większych. Jak i inne frameworki ma pewne ograniczenia, ale przede wszystkim ma ogrom zalet. Ze swojej strony zdecydowanie polecam - wzięcie się za Django było jedną z najlepszych decyzji technologicznych w moim życiu.
------------------
Browser: Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.10) Gecko/2009042523 Ubuntu/8.10 (intrepid) Firefox/3.0.10 X-FirePython/0.1
0 + -
comnt #11 bx2 2009-05-13 11:35:24
bx2 Niestety wiele osób nie rozumie filozofii Django - np. narzekania odnośnie tego, że templaty są ograniczone i nie można do nich wrzucać "normalnego" kodu pythona. Ale właśnie o to chodzi - w modelu MVC (czy MVT ;) ) templatka to tylko "widok" - miejsce logiki i skomplikowanych kalkulacji jest w modelu.

@-ja-: niezły jesteś... chyba nie do końca rozumiesz o co w tym wszystkim chodzi - nikt nie napisał, że python jest najlepszy na świecie - to tylko narzędzie, a że jest naprawdę dobrym i dojrzałym językiem warto go znać.

Jeśli zaś chodzi o zmienne prywatne w klasach - błagam Cię - poczytaj troszkę zanim głupoty napiszesz :)

A jeśli chodzi o sam język - no cóż - python jest po prostu zaje***** :D

@pako: jeśli chodzi o dispatchera - próbowałeś chociaż? Faktycznie zamiast szybciutko poprawić url-a w regexp-ie (1 linia kodu) lepiej dostosowywać cały kontroler przez godzinę żeby potem cieszyć się cały dzień (aż do następnej zmiany)..

Dobry artykuł - więcej takich proszę :)
------------------
Browser: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; pl; rv:1.9.0.10) Gecko/2009042315 Firefox/3.0.10
0 + -
comnt #12 -ja- 2009-05-13 12:43:19
-ja- @bx2

A co, zmienne prywatne są? Przecież wszystkie zmienne są publiczne, a tylko w ramach konwencji zmienne których nazwy zaczynają się od _ są inaczej traktowane przez programistów. Ale nic nie stoi na przeszkodzie żeby napisać A._a = 10 i to działa, bo jest zmienna publiczna nazywająca się _a.

Z trzeciej strony... co mam kontakt z jakimś fanatykiem Pythona to okazuje się, że zna aż 1, może 2 inne języki programowania. No właśnie, zanim zaczniecie pisać takie fanatyczne głupoty to poczytajcie nieco, poznajcie 15 innych języków to może zobaczycie, że każdy ma wady i zalety, że nie ma najlepszego języka i ważne jest to jak się pisze i jak się projektuje aplikacje a nie to jaki jest język. To zupełnie jakby mówić, że po polsku da się napisać świetną książkę, a po angielsku już nie.
------------------
Browser: Mozilla/5.0 (X11; U; Linux x86_64; pl-PL; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10
0 + -
comnt #13 pbjk 2009-05-13 13:56:10
pbjk @-ja-

A próbowałeś kiedyś użyć zamiast "_" "__" - zobacz co się teraz stanie przy próbie bezpośredniego dostępu do takiej zmiennej. Dostęp jest, ale już nie w tak oczywisty sposób.
------------------
Browser: Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.7) Gecko/2009030422 Ubuntu/8.04 (hardy) Firefox/3.0.7
0 + -
comnt #14 dAREuS® 2009-05-13 14:26:45
------------------
dAREuS

Browser: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)
0 + -
comnt #15 bx2 2009-05-13 14:55:48
bx2 @pako - sama idea hermetyzacji to koncepcja, która powstała przy pierwszych krokach w OOP. I jest słuszna - tzn. użytkownik potrafi jeździć samochodem i nie koniecznie musi wiedzieć dokładnie jak działa. Różnica polega na tym, że programista wiec co robi (najczęściej :D ) stąd też w pythonie jest podejście do zmiennych prywatnych w sposób "koncepcyjny" - jest możliwość aby je zdefiniować i nikomu to nie przeszkadza.



W twoim przypadku chodzi o coś innego - ty uparłeś się, że ktoś tu atakuje inne języki programowania np. wspomniane przez Ciebie PHP (przypominam, że skrót oznacza Personal HomePage) - przecież nikt złego słowa nie powiedział. PHP od lat jest wykorzystywane do pisania oprogramowania webowego, jest ogólnie rzecz biorąc tańszy i posiada w swoim portfolio więcej napisanych stronek - to tyle.



Pisz sobie w czym chcesz - nie ma tutaj lepszy gorszy.. Różnica polega na tym, że jako Polakowi o wiele więcej czasu zajmie ci napisanie książki po angielsku niż po polsku :P
------------------
Browser: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; pl; rv:1.9.0.10) Gecko/2009042315 Firefox/3.0.10
0 + -
comnt #16 Jan Koprowski® 2009-05-13 18:29:18
jankoprowski Uważam, że Python budzi tak wiele emocji ponieważ jest specyficzny. Obrał sobie bardzo charakterystyczną i wąską ścieżkę rozwoju a jak wszystko co kontrastowe stawia ludzi w równie kontrastowym podejściu: albo się go uwielbia, albo niecierpi - ciężko pozostać obojętnym.

Python jest takim językiem i dlatego jest tak wiele osób mówiących o nim z tak wielkim entuzjazmem. PHP moim zdaniem już np. jest językiem - zwykłym, typowym, dla mas i takich emocji już nie budzi.
------------------
Jan Koprowski

Browser: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/530.9 (KHTML, like Gecko) Chrome/2.0.180.0 Safari/530.9
0 + -
comnt #17 pako® 2009-05-13 20:51:29
pako @Restless:

1. Jeśli korzystam z frameworka, to liczę na to, że mogę użyć jego ORMa bazodanowego, a nie robić na na około przy chęci połączenia się z więcej niż jedną bazą danych. Równie dobrze mogę w takim wypadku w ogóle z ORMa nie korzystać. Połączenie się do wielu baz to po prostu podstawa przy większych projektach.

2. Widzę, że jest to odpowiedź na jęki społeczności, ale umówmy się, nie jest doskonałe. Z pierwszych rzeczy, które od razu mi się nasuwają to nie ma chociażby HAVING().

3. Jest wystarczający dla prostych zastosowań. Przy próbie połączenia więcej niż 2 tabel z wykorzystaniem sortowania i sumowania elementów z określonych kolumn - takich rzeczy się zwyczajnie w tym ORMie nie da zrobić.

4. Dobra, kwestia preferencji. Korzystałem z obu typów dispacherów i jeśli mam klepać regexpa, a zrobić to samo przez całkowicie logiczną i naturalną składnie /:controller/:action to wybieram bez zastanowienia drugą opcje.

5. A niby dlaczego nie mają mieć dostępu do contextu? Dla mnie to nieprzyjemne ograniczenie.

6. Pokaż mi proszę wywołanie filtra, w którym przekazujesz jako argumenty 4 wartości ustawione do szablonów, z czego wartościami są obiekt1.nazwa_elementu.

7. Wysyłam formularz z zaznaczoną opcją selecta. Formularz nie przechodzi z jakiegoś powodu walidacji, ustawiam dane z POST do szablonu, natomiast dane które znajdowały się w select pochodzą z modelu. Model zwraca wartości dla w selecie w int, POST to utf8. Jak zatem mam sprawdzić, którą opcje w dać 'selected' jeśli model ma wartości w INT, a dane z POST w UTF?



Django nie jest złe dla małych projektów. Jednak gdy chcemy zrobić coś niestandardowego co wymaga trochę większej elastyczności, to monolityczność tego frameworka nam na to zwyczajnie nie pozwoli.



> @pako: jeśli chodzi o dispatchera - próbowałeś chociaż?

> Faktycznie

zamiast szybciutko poprawić url-a w regexp-ie

> (1 linia kodu) lepiej

dostosowywać cały kontroler przez

> godzinę żeby potem cieszyć się cały

dzień (aż do następnej zmiany)..



@bx2: z twojego opisu powyżej wynika, że nigdy nie miałeś do czynienia z innego typu dispacherem niż regexpy. Natomiast odnośnie drugiego komentarza - to chyba nie był do mnie skierowany.
------------------
Browser: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.7) Gecko/2009030814 Iceweasel/3.0.9 (Debian-3.0.9-1)
0 + -
comnt #18 Rafał Jońca 2009-05-13 21:15:18
Rafał Jońca @pako: Wiele osób tutaj naprostowało inne kwestie, więc ja chciałbym odnieść się do tej związanej ze "słabą skalowalnością" po części z racji "nieobsługiwania" wielu baz danych (co nie jest już obecnie prawdą). W swojej karierze miałem i mam do czynienia z witrynami, które osiągają setki tysięcy page views dziennie (choć nie Django) i jakoś nigdy nie było potrzeby stosowania wielu baz danych dla głównej aplikacji (czasem jest kilka, ale już jako osobne usługi po REST).



Wniosek: nie wiązać skalowalności z obsługą wielu baz.



PS. Django skaluje się bardzo dobrze, bo to najczęściej nie ono jest źródłem zadyszki ;), no chyba ze dojdziesz do 100-200 req/s w realnych warunkach (potrafi znacznie więcej, jeśli nie ma hitów do DB).
------------------
Browser: Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10
0 + -
comnt #19 x_O 2009-06-03 19:47:41
x_O Hej mam uwagę co do pliku utils.py. Nic podobnego nie widniej we wskazaniach w dokumentacji co to za twór? Czy to poprostu twój pomysł na rozwiązanie tego problemu.

Dodatkowo wydaje mi się, że katalogi "upload" i "apalikacja" powinny być w katalogu "projekt", a nie jak w tym momencie na jego poziomie

Pozdrawiam

x_O
------------------
Browser: Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10

Komentarze

  • Aby dodać komentarz, musisz podać swój nick, treść komentarza oraz poprawnie przepisać oba słowa z obrazka (słowa muszą być rozdzielone spacją).
  • Jeśli masz problemy z odczytaniem słów, zmień zdjęcie.
  • Używamy tego zabezpieczenia, ponieważ dzięki niemu rozwija się projekt reCAPTCHA. Sugerujemy jednak, by zarejestrować się w serwisie i w ten sposób ominąć konieczność ciągłego odczytywania wyrazów.
  • W treści komentarza można używać języka formatowania BBcode.