wtorek, 8 kwietnia 2008

Google App Engine

Wczoraj wieczorem czasu ( w Polsce to był już chyba ranek ) google pokazało światu swoja najnowszą zabawkę dla programistów Google App Engine. Krótko mówiąc pozwala to na hostowanie aplikacji napisanych w pythonie na serwerach google, korzystanie z BigTable, biblioteki do obsługi użytkowników gmail. Ponieważ aplikacje siedzą w piaskownicy nie mogą zapisywać żadnych informacji na dysk (jedyny sposób to Datastore ) oraz kontaktować się z siecią ( tutaj google dało FetchURL, dzięki któremu możemy ściągać informacje po HTTP (port 80 i 443).

Udało mi się nawet zarejestrować i mam konto ( Google do testowania udostępniło 10000 kont ), ale potestuje je sobie wieczorem. Ponadto można sobie ściągnąć SDK i pobudować aplikację offline ;)

Teraz kilka moich spostrzeżeń. Całe SDK to w gruncie rzeczy biorąc zlepek kilku frameworków pythonowych ( właściwie to wycinki jednego ;)) . Mamy więc aplikację WSGI odpowiedzialną za mapowanie url-i ( mapujemy url-e za pomocą wyrażeń regularnych) do RequestHandlerów, które to obsługują poszczególne widoki. Jako język templatów google poleca templaty Django ( przez "większość" uważane za zbyt ubogie ), do obsługi formularzy biblioteki newforms z Django. Budowa modeli dla DataStore też jest bardzo podobna do tego w jaki sposób robi to Django. Ale jeżeli komuś się to nie podoba to może użyć własnego frameworka opartego na WSGI ( w FAQ-u opisane jest jak użyć Django 0.96 ). Na serwerach google jest zainstalowany Python 2.5 i oprócz bibiolteki standardowej jest Django 0.96, PyYaml oraz WebOb.

Dzięki temu że cały storage jest oparty na BigTable (które się podobno bardzo dobrze skaluje) nie wydaje mi się aby konieczne były mechanizmy cachowania w stylu memcache, itp. Sesje mogą być trzymane w BigTable, wyrenderowane strony - w BigTable, itp, itd. DataStore oferuje prosty język zapytań GQL podobny w strukturze do SQL-a przy czym z kilkoma ograniczeniami ( nie można robić join-ów), oraz mechanizm dostępu analogiczny do słownika (put, get)

Czasami zdarza mi się flame-ować na grupach na temat czy django dobrze się skaluje ( niektórzy twierdzą że się nie skaluje i nie da sie z nim nic większego zrobić ) . Jak widać po kilku modyfikacjach ( które nie zmieniają wizji całej ramówki) w samej architekturze całego serwisu, jest to możliwe.

Tak więc drodzy państwo Start Your Engines :)

wtorek, 1 kwietnia 2008

Własne pola w kolumnach listy w panelu admina

Django admin pozwala na zdefiniowanie listy pól które mają być wyświetlane w liście a panelu admina.

class MyModel(models.Model):      ....      class Admin:            list_display=['name','surname',...] 

Pola te nie muszą być stricte polami modelu ( czyli dziedziczącymi z models.Field ), ale mogą to być również zwykłe pola klasy, lub też metody. Jeżeli jest to metoda obiektu zostanie ona wywołana a jej wynik znajdzie się w kolumnie. I tak np. możemy zrobić sobie:

class MyModel(models.Model):     name = models.CharField(max_length=100)     surname = models.CharField(max_length=100)     ...      def full_name(self):         return u"%s %s"%(self.name, self.surname)      class Admin:         list_display=['login','full_name','email'] 

Dla każdego obiektu zostanie wywołana metoda full_name a wynik jej działania będzie widoczny w kolumnie "full_name"

Wynik wywołania funkcji zostanie przed pokazaniem w templacie wyeskejpowany, ale i na to twórcy django zrobili obejście. Jeżeli takiej metodzie damy atrybut allow_tags ( metody i funkcje w pythonie również mogą posiadać atrybuty ). Jeżeli np. chcemy aby taka kolumna była jakoś wyróżniona możemy zrobić to tak (przykład jak wyżej):

class MyModel(models.Model):     name = models.CharField(max_length=100)     surname = models.CharField(max_length=100)     ...      def full_name(self):         return u'%s %s'%(self.name, self.surname)     full_name.allow_tags = True     full_name.short_description = "Full name"      class Admin:         list_display=['full_name',] 

Po takiej deklaracji kolumna będzie miała nazwę "Full name", a wartości w niej znajdujące się będą miały kolor czerwony.

UWAGA: należy pamiętać o wyeskejpowaniu wartości które mogły zostać wprowadzone przez użytkownika.

W połączeniu z własnymi templatami do listy obiektów, które dziedziczą z szablonu "admin/change_list.html" możliwe jest np. dodanie możliwości masowego kasowania lub modyfikowania obiektów.

Adres strony admina dla modeli

Jeżeli chcemy pobrać adres strony admin-a dla danego modelu robimy to w następujący sposób

 from django.core.urlresolvers import reverse 
 .... 
 reverse('django.contrib.admin.views.main.change_list',None,[ModelClass._meta.app_label,ModelClass._meta.module_name])