Wilane' Weblog

jaZZ ... just another Zine Zblog

Billets dans la catégorie « django »

Django 1.2 au frigo

écrit par Ousmane Wilane, le 06/01/10 09:53.

Django 1.2 alpha 1 a été publié hier et marque le début du gèle avec quelques fonctionnalités qui n’ont pas pu atterrir à temps dans le tronc (souvent pour de très bonnes raisons, ces gars sont des chefs ! Merci !). Vous pouvez jeter un coup d’oeil aux notes de publication

Protection CSRF

Pas mal de modifications en ces terres de sable mouvant. Si vous n’êtes pas intéressé par les détails il faut juste vous rappeler que par défaut vous aurez besoin de la tag csrf_token dans vos formulaires:

  <form method="POST">{% csrf_token %}
  {# comme d'habitude ici #}
  </form> 

Tag de template if

Plus besoin de grandes contorsions pour faire un peu de logiques d’affichage, la tag if est devenu super extra méga futée:

{% if mavar == "x" %}
  mavar est donc x. corollaire if(not)equal
{% endif %}

{% if mavar != "x" %}
  zut ! mavar n'est pas x
{% endif %}

{% if "bc" in "abcdef" %}
  Ben puisque "bc" est dans "abcdef"
{% endif %}

Vous pouvez utilisez les autres opérateurs classiques (<, >, <=, >=) telle que vous les connaissez par ailleurs. Notez que ces opérateurs peuvent être combiné pour exprimer des expressions complexes, il faudra alors faire attention à la précédence des opérateurs puise que les parenthèses ne sont toujours pas acceptées dans les tags de template.

Formats locaux avec I18N

Il est maintenant facile d’accéder aux formats sensible à la configuration locale:

from datetime import datetime
from django.utils import formats

formats.date_format(datetime.now(), 'DATETIME_FORMAT')
#u'Jan. 6, 2010, 9:22 a.m.'

date_format = formats.get_format('DATE_FORMAT')
datetime_format = formats.get_format('DATETIME_FORMAT')
time_format = formats.get_format('TIME_FORMAT')

date_format,datetime_format,time_format
#('N j, Y', 'N j, Y, P', 'P')

MultiDB

Si vous avez besoin d’accéder à plusieurs bases dans votre application, rien de plus simple, Django à fait peau neuve pour le plaisir de vos doigts et de vos yeux. En lieu et place des paramètres de configuration que vous connaissiez déjà il suffit juste de mettre:

DATABASES = {
    'default': {
        'NAME': 'mabase',
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'USER': 'toto',
        'PASSWORD': 'passerp0s'
    },
    'utilisateurs': {
        'NAME': 'mabaseuser'
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'nono',
        'PASSWORD': 'passersurtoutp0s'
    }
}

# ET pour sauver dans la base mysql un objet par exemple:
mon_obj.save(using='mabaseuser')

Les cas d’utilisation sont légions, vous pouvez par exemple songer à une base répliquée en temps réel où les répliquât seraient utilisés comme base de lecture pour désengorger la base principale, vous pouvez aussi songer au sharding et autres bases de données hérités. Toute les API autour de l’ORM se sont mis sur leurs 31, 5 jours après la saint-sylvestre pour l’accueil de multidb pour votre grand plaisir.

Autres gâteries

  • Validation de modèles (utilisable en l’état avec les ModelForm)
  • Les modèles peuvent utiliser un BigInt 64 bit
  • Un bon raccourcis de sortie lorsque les tests rencontrent un pépin: Lève vite le camp !
  • Cache des templates
  • Votre EmailBackend si vous voulez faire vos trucs à vous
  • Le framework des Messages juste pétillant
  • Champs en lecture seul dans l’admin
  • … Et bien d’autres délires encore plus chanmé …

Le Bébé est attendu le 09/03/2010, merci à tous de tester et de remonter les anomalies constatées.

Django MultiDB

écrit par Ousmane Wilane, le 31/12/09 10:01.

Pour ceux qui ne suivent pas le développement de Django de près, le projet GSoc 2009 MultiDB de Alex Gaynor a foulé le sol du trunk, et comme un bonheur n’arrive jamais seul, PostgreSQL 8.5 alpha3 est publié avec un support natif d’une réplication maître-esclave.

Nouveautés Django 1.1

écrit par Ousmane Wilane, le 21/09/09 01:52.

Un petit survol des nouveautés de Django 1.1 sur http://guente.wilane.org. Les sources rst sont disponible, voir lien dans les slides. Voir l’excellente présentation d’Alex Gaynor lors de DjangoCon2009 sur les aggrégats

django.forms et datepicker

écrit par Ousmane Wilane, le 21/06/09 22:34.

jQuery dispose de pléthores de greffons avec une superbe façon de les packager depuis le site web avec les styles bien mariés au style de votre site. Parmi les greffons les plus célèbres on peut citer ui.effects.*, ui.accordeon, ui.dialog, ui.draggable, ui.droppable, ui.progressbar, ui.resizeable, ui.selectable, ui.slider, ui.sortable, ui.tabs et ui.datepicker.

La définition d’éléments de style avec Django est plutôt simple, et le deviendra encore plus si les travaux SoC 2009 de Zain Memon sur admin-ui venaient à être acceptés. Au niveau des éléments de formulaire, il suffit généralement de définir l’attribut `attrs' (dictionnaire) du widget que vous souhaitez associer à votre élément de formulaire:

#pour un champ date
forms.DateField(
            widget=forms.DateInput(attrs={'class':'datepicker'}, 
                                   format='%d-%m-%Y'),
            input_formats=['%d/%m/%Y %H:%M:%S',
                           '%d-%m-%Y %H:%M',
                           '%d-%m-%Y',
                           ],
            )

Une façon élégante d’affubler tous les champs de type date de l’attribut `class="datepicker"' est d’utiliser l’attribut de classe non documenté de la classe Form ou ModelForm `formfield_callback', par exemple:

def mon_datefield_perso(f):
    if isinstance(f, models.fields.DateField):
        return forms.DateField(
            widget=forms.DateInput(attrs={'class':'datepicker'}, 
                                   format='%d-%m-%Y'),
            )
    else:
        return f.formfield()

class MonForm(forms.ModelForm):
    formfield_callback = mon_datefield_perso
   
    class Meta:
        model = Monmodele

Une fois définit ce callback, il vous suffira d’utiliser dans votre template de base un appel générique à .datepicker() pour tous les éléments de la classe .datepicker:

$(function() {
    $('.datepicker').datepicker({inline: true});
});

La technique marche également pour un FormSet, *formset_factory utilise aussi ce type de callback (par défaut lambda f: f.formfield()) :

FactureFormSet = modelformset_factory(MonModele, 
                                      form=MonForm, 
                                      formfield_callback=mon_datefield_perso
                                     )

Migration de Schéma/Données

écrit par Ousmane Wilane, le 18/05/09 18:59.

La migration de données et de schéma dans le cadre d’un framework est une tâche difficile dans son implémentation. Il consiste en gros à se souvenir des modifications apportées au schéma (tables, vues, etc) et éventuellement aux données dans le schéma pendant tout le cycle de vie de l’application. Le but étant clairement de gérer la persistance d’attributs inexistants ou supprimés depuis la dernière synchronisation avec le support de persistance (SGBD-R, CouchDB, etc).

Dans l’écosystème Django, South semble le plus aboutit pour la gestion de ce qui est désormais connu sous le vocable de Migration. Parmi les éléments qui font la force de South on peut citer le fait qu’il génère un script de migration en Python très propre et très lisible avec une API Base de données et un ORM par lequel on a accès aux modèles (South a un grand nombre de vote de la communauté pour une intégration à django/contrib éventuelle et nombre de développeurs Django soumettent régulièrement des patchs à South:

from south.db import db
from django.db import models
from core.models import *

class Migration:
    
    def forwards(self, orm):
        "Write your forwards migration here"
    
    def backwards(self, orm):
        "Write your backwards migration here"
    
    models = {
        'monappli.monmodele': {
            'unedate': ('models.DateField', ["'Date de Heu'"], {}),
        },
        'mon.monautremodele': {
            'monmodele': ('models.ForeignKey', 
                         ["orm['monappli.monmodele']"], 
                         {'related_name': "'boubougolo'"}
                         ),
        },
    }
    
    complete_apps = ['monappli']

Les méthodes `forwards()` et `backwards()` peut être utilisées pour toute les manipulations de données souhaitées et cela avec l’aide précieuse l’API db. Un très bon exemple est donné dans le tutoriel, il consiste à remplacer un champ nom_complet avec les champs prenoms et noms en copiant les données déjà définit dans le nom_complet:

# Exemple du tutoriel3: http://south.aeracode.org/wiki/Tutorial3
 def forwards(self, orm):
        db.add_column('monappli_monmodele', 
                      'prenoms', 
                      models.CharField(max_length=150)
                     )
        db.add_column('monappli_monmodele', 
                      'noms', 
                       models.CharField(max_length=150)
                     )

        for item in orm.MonModele.objects.all():
            pass # ... Une copie de données par exemple ...
        
        db.delete_column('monappli_monmodele', 'nom_complet')

Il est courant de ne penser à la migration que lorsqu’on a commencé les premiers tests d’une applications après avoir introduit quelques données de test. South permet simplement de mettre en œuvre une migration après coup:

Avec la version >= 0.5:

./manage.py startmigration monappli --initial
./manage.py migrate monappli

Avec les versions antérieures:

./manage.py convert_to_south monappli

South support l’auto-détection de modification lorsque l’application est gélées (dans settings.py):

SOUTH_AUTO_FREEZE_APP = True

En auto-détection il suffit simplement après des modifications dans les modèles de demander l’auto-détection:

python manage.py startmigration monappli nom_migration --auto

Et si les modifications détectées sont correctes alors il suffit de lancer la migration:

python manage.py migrate monappli

Celle-ci se traduira par une série de directives de type DDL sur le support de stockage de façon agnostique aux support de stockage comme l’ORM de Django lui-même

Pour couronner le tout, South-0.5.2 est disponible dans sid sous le nom python-django-south

South est relativement bien documenté, vous pouvez suivre le tutoriel qui donne tous les éléments pour être à l’aise avec South. Vous pouvez aussi lire l’article de Andrew Godwin sur les choix d’architecture de South.

Erlang aussi dans le web framework

écrit par Ousmane Wilane, le 14/05/09 12:19.

Avec Nitrogen Erlang est en plein dans la danse. Avec Seaside (Smalltalk), Django (Python) et ses frères, Weblocks (Common Lisp), HApps (Haskell) et Rails (Ruby), c’est une vraie alternative sérieuse qui apporte la force d’Erlang sur la table (remise à l’échelle innée).

Pour le côté bling bling Nitrogen fait un choix qui devient standard de fait: jQuery