Présentation accessible en ligne sur : http://larlet.fr/conferences/django/
IZ __name__ KINDA LIKE "__main__"?
IZ BIGNESS ARGZ OK KINDA LIKE 1?
N CAN HAS 100
NOPE?
N CAN HAS NUMBR ARGZ LOOK AT 1!!
Attention le C du MVC correspond ici au V, et le V au T !
Via des liens directs :
urlpatterns = patterns('',
(r'^archives/$', archives),
)
ou basé sur des expressions régulières :
urlpatterns += patterns('',
(r'^archives/(?P<year>\d{4})/$', archives_year),
)
Via un ORM simple
from myproject.blog.models import Post
def archives(request):
posts = Post.objects.all()
permettant aussi de faire des choses compliquées
posts = Post.objects.filter(is_online=True).distinct()
ou même du SQL selon les besoins.
Passage d'un dictionnaire à un template
from django.shortcuts import render_to_response
from myproject.blog.models import Post
def index(request):
latest_posts = Post.objects.all()[:5]
return render_to_response('blog/index.html',
{'latest_posts': latest_posts})
Les objets QuerySet sont des itérateurs
Un langage de template simple :
<ul>
{% for post in latest_posts %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
Il suffit de différencier les {% blocs %} des {{ variables }}
En restant extrêmement basique...
class Post(models.Model):
title = models.CharField(maxlength=250,)
slug = models.SlugField(prepopulate_from=('title',))
content = models.TextField()
pub_date = models.DateTimeField()
tags = models.ManyToManyField(Tag)
def get_absolute_url(self):
return ('myproject.blog.views.item', str(self.id))
get_absolute_url = permalink(get_absolute_url)
Il est bien entendu possible d'ajouter d'autres fonctions
En ajoutant une seule ligne au modèle :
class Post(models.Model):
[...]
class Admin:
pass
Possibilité d'utiliser les modèles via un shell :
$ python manage.py shell >>> from myproject.blog.models import Post >>> Post.objects.all() [<Post: Les JFP une réussite !>]
On distingue les ressources de l'agrégation :
urlpatterns = patterns('',
(r'^/blog/(?P<year>\d{4})/(?P<month>\d{2})/ »
(?P<day>\w{1,2})/(?P<slug>\w+)/$', blog_post),
(r'^/blog/$', post_list),
)
Il est possible d'ajouter des archives par date, etc
On distingue les ressources de l'agrégation :
def blog_post(request, year, month, day, slug):
post = get_object_or_404(Post, slug = slug)
return render_to_response('blog/item.html', {'post': post})
def post_list(request):
latest_posts = Post.objects.all().order_by('pub_date')[:10]
return render_to_response('blog/index.html',
{'latest_posts': latest_posts})
Il est bien entendu possible d'ajouter d'autres fonctions
Affichage de la liste des billets de blog :
<div>
{% for post in latest_posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
{{ post.content }}
<p>{{ post.pub_date }}</p>
{% endfor %}
</div>
Création d'une classe, association d'une URL
class LatestPosts(Feed):
title = "Twitter n'a qu'a bien se tenir"
link = "/blog/"
description = "Ma vie, minute par minute."
def items(self):
return Post.objects.order_by('-pub_date')[:5]
urlpatterns = patterns('',
(r'^feeds/(?P<url>.*)/$',
'django.contrib.syndication.views.feed',
{'feed_dict': { 'blog': LatestPosts }}))
L'objectif est de gagner du temps :
Les paramètres par défaut suffisent dans la plupart des cas.
Vous pouvez étendre un template de base :
{% extends "base.html" %}
{% block content %}
<p>
Le contenu de ce paragraphe va s'afficher dans la
partie content du template de base, il est possible
d'avoir plusieurs niveau d'héritage et donc
plusieurs templates de base.
</p>
{% endblock %}
Gain en généricité et donc en rapidité de développement.
Permettent la récupération, le traitement ou l'affichage de données
{{ post.content|markdown }}
<p>Le {{ post.pub_date|date:"j F Y"|lower }}</p>
Il est possible de créer sa propre bibliothèque.
Les morceaux de codes redondants peuvent être factorisés dans des inclusion_tag dynamiques.
Utilisation de gettext possible à différents niveaux :
Traitement comme des locales classiques.
class PostManager(models.Manager):
def get_query_set(self):
qs = super(PostManager, self).get_query_set()
return qs.filter(is_online=True)
class Post(models.Model):
[...]
objects = models.Manager()
published = PostManager()
Permet de distinguer Post.objects.all() et Post.published.all() lorsque l'on manipule les objets.
Envoi d'un mail à chaque nouveau billet :
def rss_by_mail(sender, instance):
[...]
send_mass_mail([...])
dispatcher.connect(rss_by_mail,
signal=signals.post_save, sender=Post)
Les signals permettent d'effectuer des tâches de routine au niveau des modèles. Il est par exemple possible de mettre en place une historisation grâce à ce système.
Exemple pour REST :
class HttpMethodsMiddleware(object):
def process_request(self, request):
if request.POST and 'verb' in request.POST:
if request.POST['verb'] in ['PUT', 'DELETE']:
request.method = request.POST['verb']
return None
Récupération du verbe HTTP dans le champ caché 'verb' de tous les formulaires qui sont POSTés. On peut ensuite gérer les actions associées dans les vues.
Implémentation des doctests et des unittests
c = Client()
c.get('/blog/')
c.post('/blog/comments/', {'name':'david', 'content':'lol'})
De nombreuses autres applications sont disponibles :
Difficile à mesurer, mais :

Publicité : django-fr recherche des traducteurs :-).
Et bien sûr tous les développeurs Django !