South est une application Django qui permet de migrer sans (trop de) soucis le modèle de base de données. La version 0.7 de South est sortie dernièrement et apporte des améliorations dans la reconnaissance du modèle. Toutefois, afin de mieux permettre cette reconnaissance, South 0.7 introduit une rupture de compatibilité pour la détection des "Custom fields"
Un "custom field" est une classe de champ de modèle qui ne vient pas de Django mais que vous avez vous-même crée.
Par exemple, j'utilise sur une application une classe de champ : 'MenuUrlField' qui dérive de 'CharField' et qui permet de vérifier que la valeur entrée est bien compatible avec une expression régulière donnée.
class MenuUrlFormField(RegexField):
"""Validation of URLS"""
default_error_messages = {
'invalid': _(u"Enter a valid URL"),
}
validation_regex = re.compile(r'^(https?://\w|/)[\w/\.-\?\=&\%\:]*$')
def __init__(self, *args, **kwargs):
super(MenuUrlFormField, self).__init__(MenuUrlFormField.validation_regex, *args, **kwargs)
class MenuUrlField(models.CharField):
def __init__(self, verbose_name=None, name=None, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 200)
models.CharField.__init__(self, verbose_name, name, **kwargs)
def formfield(self, **kwargs):
defaults = {'form_class': MenuUrlFormField}
defaults.update(kwargs)
return super(MenuUrlField, self).formfield(**defaults)
Malheureusement, l'utilisation de ce type de champ pose un problème à South 0.7 qui ne sait pas comment contruire un champ MenuUrlField. L'introspection du modèle de base de données va donc échouer pour cette raison.
Il faut donc signifier à South comment construire un "Custom Field" en définissant des règles d'introspection du code.
On ajoute alors dans le code, (dans mon cas, j'ai ajouté le code suivant dans le models.py la où se trouve aussi la classe menuUrlField):
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], [".*\.flatcms\.models\.MenuUrlField"])
Ici, la construction d'un MenuUrlField est la même que celle d'un CharField, il n'y a donc pas de règles particulières à fournir a South. On appelle donc la fonction add_introspection_rules en lui passant en argument une liste de règles d'introspection vide et en second une liste d'expression régulières qui lui permettra d'identifier notre "Custom field"
Pour les "custom fields" dont le constructeur diffère de la classe parente, il est nécessaire de définir une règle afin que South sache quels sont les arguments supplémentaires et comment construire l'objet. Je vous invite à lire le tutoriel de South qui décrit très bien comment définir ces règles.