15 maja 2007

Zaczynam z Django 4 - pierwsza strona

Czas najwyższy, żeby zobaczyć efekty jakiejś własnej pracy, bo jak do tej pory, to głównie automaty wykonywały za mnie wszystkie czynności.
Czas wykorzystać konfiguracje URL-i, którą już raz zmieniałem (plik urls.py). Pierwsza wprawka w DB (rozdział 3) po uproszczeniu przeze mnie wygląda następująco:


from django.http import HttpResponse
import datetime

def current_datetime(request):
html = "Jest %s" % datetime.datetime.now()
return HttpResponse(html)


Zapisujemy to do pliku views.py.
Warto sobie znowu na boku odpalić terminal i ./manage.py shell a potem: from mdjango.mbegin.views import *
(wszystkie kolejne sprawdzenia będę najpierw przeprowadzał w konsoli, więc nie będę juz pisał o jej odpalaniu).
Odpalamy current_datetime(), powinien nam się pojawić błąd. Wynika on z tego, że próbowałem wykorzystać konsolę do wypisania HTTPResponse.
Teraz już zmiana konfiguracji URL-i: dodajemy import pliku z widokami i konfiguracje przekierowania w przypadku wywołania adresu http://localhost:8080/czas/.
plik urls.py wygląda teraz tak:


from django.conf.urls.defaults import *
from mdjango.mbegin.views import *

urlpatterns = patterns('',
(r'^czas/', current_datetime),
(r'^admin/', include('django.contrib.admin.urls')),
)


I powoduje pokazanie....błędu. Przy okazji okazuje się jak django pokazuje błedy, jak dla mnie całkiem przejrzyście i tego właśnie bym oczekiwał od informacji o błędzie. Jest stos, jest zapytanie, jest konfiguracja. Chyba nie muszę już pisać o kolejnym plusie. Zauważyłem również możliwość przełączania pomiędzy trybami oglądania informacji o błędzie. Sam błąd to: AttributeError at /czas/ 'function' object has no attribute 'rindex' oznacza on, że DB jest do przodu w stosunku do mojego Ubuntu. Tak jak napisałem URL-e docelowe, można je pisać dopiero od wersji 0.96 a ja mam 0.95. Na razie daruję sobie podnoszenie wersji (warto znać różne metody obejścia problemu). Rozwiazaniem jest napisanie nazwy funkcji jako stringa poprzedzonego nazwą aplikacji i modułu. Więc ostatecznie wygląda to tak:


from django.conf.urls.defaults import *
from mdjango.mbegin.views import *

urlpatterns = patterns('',
(r'^czas/', 'mbegin.views.current_datetime'),
(r'^admin/', include('django.contrib.admin.urls')),
)


Przy okazji upraszczania zrobiłem jeszcze jeden błąd: W ramach upraszczania nie napisałem parametru request dla funkcji current_datetime, jest on oczywiście potrzebny. Po poprawieniu usterek widać skromną, ale własną, pierwszą stronę wykonaną przy uzyciu django. Teraz już pójdzie z górki, ale to już w następnym odcinku. A na dzisiaj ostatni element, żeby mieć poprawny czas, trzeba ustawić TIME_ZONE = 'Europe/Warsaw' (lub jak kto woli mieć ustawione) w settings.py, no chyba, że ktoś mieszka w tej samej strefie czasowej co Chicago

07 maja 2007

Zaczynam z Django 3 - baza danych

Zaczynam z Django 3

Jako, że mam już wcześniej przygotowaną bazę danych, to warto byłoby z niej skorzystać. Do tego służy znalezione dopiero w 17 rozdziale DB python mysite/manage.py inspectdb, warto sobie przejrzeć co się produkuje na ekran, a potem w najprostszy sposób zapisać to do pliku z modelem: ./manage.py inspectdb > mbegin/models.py
(DB: python mysite/manage.py inspectdb > mysite/myapp/models.py). Generowane jest coś w tym stylu:


class Categorie(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(maxlength=600)
description = models.TextField(blank=True)
class Meta:
db_table = 'categories'

Ponieważ tabele miały nazwy przystosowane do innego frameworka, więc ich nazwy są w liczbie mnogiej. Wygląda na to, że Django korzysta z prostej zasady, odejmij od liczby mnogiej 's' i masz liczbę pojedynczą. Nie zawsze się to sprawdza, w DB piszą, żeby przejrzeć i oczyścić wygenerowany model, z pewnością to później uczynię, zgodnie z zasadami podanymi we wspomnianym rozdziale 17. Druga zastanawiająca rzecz, to wartość maxlength (w bazie pola są varchar(200) a w modelu 600), trzeba będzie doczytać o sposobie kodowania znaków. Niestety bezpośrednio w DB nic na ten temat nie piszą.
Żeby sprawdzić, czy model działa można skorzystać z ./manage.py shell. Jeżeli wcześniej zainstalowaliśmy sobie IPythona, to mamy w tej chwili całkiem sympatyczne środowisko pracy z bazą danych, a właściwie z jej modelem. Śmiem przypuszczać, że będzie to też dobre miejsce do np. uruchamiania unit testów. Żeby skorzystać z modelu jakiejś tabeli, starczy wpisać from project.app.models import nazwa_modelu czyli na przykładfrom mdjango.mbegin.models import Categorie, a później już można Categorie.objects.values() (wartości z rekordów), albo Categorie.objects.count() (liczba rekordów). Kolejny duży plus dla Django, można sprawdzić od razu jak działa model, zanim go użyjemy w aplikacji. Na razie phpmyadmina użyłem tylko do sprawdzenia, czy model się zgadza, większość potrzebnych operacji można teraz z poziomu powłoki wykonać, mając pewność, że jest się podłączonym do właściwej bazy itp.

04 maja 2007

Zaczynam z Django 2

Jedziemy dalej, zgodnie z tym co napisane na utworzonej wcześniej (http://piotrbla.blogspot.com/2007/05/zaczynam-z-django.html) stronie projektu. W pliku settings.py ustawiamy fragment dotyczący bazy danych (od DATABASE_ENGINE do DATABASE_PORT. Dwa ostatnie, na czas testów, można zostawić puste. Przy okazji warto zauważyć, że plik z ustawieniami to źródła w Pythonie, więc obowiązują wszystkie reguły języka. Dzięki temu piszemy też cały czas w jednym języku. Oprócz bazy danych ustawiam też dane administratora.

Po ustawieniu bazy danych generujemy pierwszą aplikację: ./manage.py startapp mbegin (na wygenerowanej stronie projektu: python mdjango/manage.py startapp [appname]). Powstaje katalog (u mnie mbegin) w którym są puste pliki dla modeli i widoków (models.py i views.py). Przy generacji mały problem z kodowaniem pliterek w nazwisku administratora, na razie odpuszczam (rezygnuje z pliterek), jak później będzie trzeba to zgłębię temat.

Kolejną rzeczą dającą szybkie efekty jest panel administratora (mały chwilowy przeskok do 6 rozdziału DB). W pliku settings.py w sekcji INSTALLED_APPS dodajemy wpis 'django.contrib.admin', później uruchamiamy ./manage.py syncdb (DB: python manage.py syncdb) co powoduje wygenerowanie tabel administracyjnych w bazie danych. Przy pytaniu o superusera warto od razu go utworzyć (później robi się to według DB przy pomocy skryptu /django/contrib/auth/create_superuser.py. Ja przy pomocy locate create_superuser.py znalazłem ten skrypt w następujących lokalizacjach:
/var/lib/python-support/python2.4/django/contrib/auth/create_superuser.py
/var/lib/python-support/python2.5/django/contrib/auth/create_superuser.py
/usr/share/python-support/python-django/django/contrib/auth/create_superuser.py


Według DB trzecim etapem generowania panelu jest dopisanie do pliku urls.py (w projekcie)
urlpatterns = patterns('',
(r'^admin/', include('django.contrib.admin.urls')),
)

a w moim przypadku było to odkomentowanie tej linijki w rzeczonym pliku. Próbuję sprawdzić, stwierdzam, że niepotrzebnie wcześniej restartowałem mini serwer (zmiany pojawiają się od razu po nagraniu pliku). Niestety (jednak to jakoś przeżyję) nowe zmiany spowodowały, że dotychczasowa strona główna zgłasza błąd (w tym miejscu warto zauważyć, że wszystkie komunikaty o Django jakie do tej pory widziałem prowadziły do rozwiązania). Działa natomiast podstrona /admin
http://localhost:8080/admin/ logujemy się, i ukazuje się w pełni GOTOWA estetyczna strona administracyjna, z możliwościami przeglądania i filtrowania danych, dodawania grup, użytkowników itp. Innymi słowy, coś co powinno być wszędzie.

Podstawy zarządzania użytkownikami mam całkowicie z głowy, co w porównaniu z innymi frameworkami znowu wygląda obiecująco.

Zaczynam z Django

Zacząłem właśnie próbować użyć django, o którym tak wiele dobrego się naczytałem (choćby tutaj).

Chciałbym przy pomocy django zrealizować jeden mały, ciekawy i innowacyjny projekt, o którym myślę od dawna. Jak django będzie współpracował, to czekają już kolejne pomysły.

Taka ciekawostka: przy okazji rozmowy o django, wyszedł jak zwykle problem wymowy. Dobrze poinformowane źródła mówią, że mówi się dżangoh (bezdźwięczne d, oh przechodzące w oł ;) ).

Jako towarzysza wędrówki wybrałem: DjangoBook, rozwiązań problemów będę poszukiwał najpierw w tej dostepnej na licencji GNU książce. Na chwilę obecną jeszcze nie wszystkie jej rozdziały są napisane (większość jest), więc czasami trzeba będzie wesprzeć się wyszukiwarką.

Zestaw startowy już mam: Linux (Ubuntu DD->EE->FF), Python, Django, Mysql. Wszystko do znalezienia w synapticu. Oczywiście można używać django z innymi popularnymi bazami danych (jak i bez żadnej bazy, co też kiedyś zweryfikuje). W DjangoBooku (dalej DB) piszą, żeby sprawdzić czy ma się mysql-python, ja mam w Ubuntu python-mysqldb i wygląda, że to właśnie ten pakiet. Dodatkowo oczywiście warto sprawdzić czy działa phpmyadmin (niestety, na chwilę obecną pod Linuksa brak IMHO lepszego narzędzia, można jeszcze z kexi próbować).

Warto wspomnieć przy okazji o mojej znajomości Pythona. Napisałem kilka (naprawdę kilka) skryptów (wielkości, jak ja to mówie, ekranu). Trochę czytałem o języku (w tym jedną średniej wielkości książkę), interesuje się nim od dawna. Zawodowo programowałem jednak zawsze w innych językach. To co _mi_ w Pythonie podoba się najbardziej to załączone bateryjki i wymuszanie wcięć (jak ktoś poprowadzi zajęcia z programowania dla poczatkujących w jakimkolwiek języku C-podobnym, to będzie wiedział, dlaczego to jest plus języka). Znajomość Django: słyszałem, że dobry i nic więcej. Czyli: Python 4/10, Django 1/10.

Bazę danych do mojego projektu mam juz prawie gotową, więc raczej nie będę się nad nią specjalnie pochylał.

Na początek w terminalu przechodzimy do swojego katalogu ze stronami (u mnie public_html i piszemy: django-admin startproject mdjango (w DB piszą: django-admin.py startproject mysite, ale instalacja django z pakietu dodała gdzieś elegancko skrypt i wie, że to pythonem się uruchamia). Z tego co na chwilę obecną wiem, Django może przechowywać kilka aplikacji w jednym projekcie.
Projekt przechowuje ustawienia bazy danych, opcji Django i aplikacji.
Powstają następujące pliki: __init__.py, manage.py, settings.py, urls.py.
Jak będą potrzebne to napiszę do czego służą.
Tak powstałą stronę można od razu sprawdzić przy pomocy wbudowanego mini serwera http. Wystarczy go uruchomić (w katalogu mdjango): ./manage.py runserver (znowu DB podaje dłuższą wersję: python manage.py runserver). Ja akurat mam domyślny port (8000) zajęty, więc dostaje błąd: Error: That port is already in use. Port zmienia się trywalnie: ./manage.py runserver 8080 (DB: python manage.py runserver 8080). Po wejściu na http://localhost:8080/ widzimy od razu działającą stronę projektu ze wskazówkami. Czas na pierwszą ocenę: z kilku przeze mnie wypróbowanych frameworków (w tym RoR i CakePHP) Django na tym etapie wygrywa, czas dojścia do tego punktu był po prostu najkrótszy.