Z archiwum Django: Znikające elementy listy.

Opublikowano 17 sierpnia 2010 z tagami: , ,

W „Archium X” Mulder i Scully prowadzili śledztwa, które nie dały się wyjaśnić na drodze konwencjonalnego rozumowania (via wikipedia). Nie inaczej jest podczas codziennych potyczek z programowaniem (i nie tylko). Czasami zdarzają się przypadki, które na pierwszy rzut oka powinny zachowywać się całkiem inaczej….

Weźmy przykładowo formę (np. ModelForm) prezentującą relacje Many to many. W momencie gdy submitujemy taką formę, wewnątrz request.POST (lub form.data) powinniśmy znaleźc listę numerów id obiektów, które wybraliśmy:

np. taką:

... 'permissions': [u'1', u'5', u'18', u'24'], ...

Idąc tym tokiem rozumowania, wewnątrz request.POST['permissions'] powinna się znaleźć owa lista. Ale czy na pewno?

Koszerne praktyki: reverse(), @permalink i {%url%}

Opublikowano 2 lipca 2010 z tagami: , , , ,

Dzisiaj postanowiłem w krótkim i szybkim poście wyjaśnić jak i dlaczego powinno się używać wymienionych w tytule konstrukcji. Wszystkie powiązane są z jednym tematem – zarządzaniem URLami w Django i w znacznym stopniu ułatwiają utrzymywanie nad nimi kontroli. Ale zacznijmy od początku…

DRY

… czyli Don’t Repeat Yourself. Zasada ta mówi, że kodu nie powinno się przeklejać, a często powtarzalne zadania separować i odwoływać się do nich z innych miejsc. Nie inaczej jest z URLami. Weźmy standardowy przykład URLa prowadzącego do pojedyńczego postu np. /post/(id)/ i zastanówmy się w ilu miejscach możemy go zdefiniować? Pierwsze i oczywiste – w pliku urls.py pisząc jego definicję:

urlpatterns = patterns('',
          (r'^post/(?P<post_id>\d+)/$', 'blog.views.post'),
)

Drugi raz możemy go powtórzyć w funkcji get_absolute_url w definicji modelu:

def get_absolute_url(self):
          return "/post/%s" % self.id

Możemy go wykorzystać przy tworzeniu widoku zajmującego się dodawaniem komentarzy lub edycją postu:

return HttpResponseRedirect("/post/" + form.id)

Lub w przypadku każdego linku który piszemy na stronie

<a href="/post/{{ post.id }}/">{{ post.title }}</a>

A co jeżeli stwierdzisz, że zamiast /post/ lepsze będzie /blog/?

Wtedy musisz poprawić adres we wszystkich wymienionych wyżej miejsach. Albo.. możesz zrobić raz a dobrze i potem zmieniać tylko w jednym miejscu. Do tego celu potrzebne będą wymienione w tytule konstrukcje. Jak zatem zapisać powyższe przykłady w wersji „koszernej”?

Definicja URLa:

urlpatterns = patterns('',
          url(r'^blog/(?P<post_id>\d+)/$', 'blog.views.post', name='blogpost'),
)

Warto zwrócić uwagę na pogrubione miejsca. Zamiast zapisywać URL jako tuple korzystamy z funkcji url() przyjmującej argument name nadający danemu URLowi nazwę (w tym wypadku blogpost) – którą będziemy się później do niego odwoływać. To ważny moment ponieważ jest to jedyne miejsce, gdzie zapiszemy URL w takiej postaci.

get_absolute_url

@models.permalink
def get_absolute_url(self):
          return ('blogpost', (), { 'post_id': self.id })

Dodajemy dekorator @models.permalink i zamiast zwracać string z URLem zwracamy tuple, który następnie (przetworzony przez dekorator) automatycznie zmienia się w odpowiedni URL. Proces ten nazywamy „rozwiązywaniem” URLi.

A jak rozwiązać dowolny URL w dowolnym miejscu?

Służy do tego funkcja reverse()

from django.core.urlresolvers import reverse
return HttpResponseRedirect(reverse('blogpost', kwargs={'post_id':form.id}))

A templaty?

<a href="{% url blogpost post_id=post.id %}">{{ post.title }}</a>

I nie pozostało mi nic innego jak zachęcić do stosowania koszernych praktyk podczas pisania własnych aplikacji. ;)

Wtyczki, pluginy, komponenty – Aplikacje wielokrotnego użytku w Django – Odcinek 3: django-pagination.

Opublikowano 23 marca 2010 z tagami: , , ,

django-pagination to aplikacja, która służy do dzielenia długich list elementów na numerowane strony (tzw. „paginacja”). Korzyści wynikające z takiego rozwiązania są oczywiste – zamiast ładować ogromną ilość informacji do przeglądarki i tworzyć nieskończenie długą listę, można ją łątwo i wygodnie podzielić na mniejsze strony, co ułatwia nawigację. Ponieważ paginacja jest stałym elementem prawie wszystkich stron internetowych aplikacja z nią związana musiała pojawić się w tej serii. Tym bardziej, żę podobnie jak w przypadku django-tagging django-pagination jest bardzo łatwa w użyciu.

Wtyczki, pluginy, komponenty – Aplikacje wielokrotnego użytku w Django – Odcinek 2: django_tagging

Opublikowano 19 marca 2010 z tagami: , , ,

Dzisiaj opowiem o aplikacji nie tyle najbardziej przydatnej (przecież nie w każdym projekcie korzysta się z tagów) co wzorowo napisanej jeżeli chodzi o „reużywalność”.

django-tagging to aplikacja, która rozpoczęła swój żywot 3 lata temu (via historia commitów na stronie projektu) i w ciągu tego czasu urosła do prawdziwego kombajnu, zajmującego się wszystkim począwszy od dodawania tagów po rysowanie choinekchmurek.

W poście pokażę trzy przykładowe zastosowania aplikacji:

Wtyczki, pluginy, komponenty – czyli aplikacje wielokrotnego użytku w Django. Odcinek 1: django_extensions

Opublikowano 17 marca 2010 z tagami: , , ,

Ponieważ na blogu od bardzo dawna nic się nie pojawiło (a tym bardziej nic szczególnie ciekawego) postanowiliśmy (właściwie to ja postanowiłem) rozpocząć na nim działalność swego rodzaju edukacyjną. Być może dzięki temu domena nie będzie stała odłogiem i wreszcie znajdzie swoich odbiorców. ;)

Ale do rzeczy. Ponieważ lwią część każdego dnia spędzam na pisaniu w Django, postanowiłem rozpocząć serię postów opisującą najważniejszy aspekt tego frameworka – tworzone przez społeczność aplikacje nadające się do ponownego użytku. O samym frameworku możecie poczytać na stronach django.pl, w bibliotece riklaunima, lub po angielsku na stronie projektu.

Następna strona »