Il y a quelques jours, avec l'installation du dépôt de snippets "Cab", je me suis retrouvé avec un problème fort ennuyeux.

Le problème était le suivant : l'application cab a définit un certain nombre de motifs d'url non compatibles avec mon installation locale. Ainsi, mon dépot de snippets étant disponible à l'adresse http://localhost:8000/snippets/, il était tout naturel de penser avoir http://localhost:8000/snippets/languages/python pour avoir la page listant les snippets fait en python. Et bien non, l'auteur de Cab avait mis un schéma d'url différent, ce qui fait que cela me renvoyait sur http://localhost:8000/languages/python et m'affichait une belle erreur 404.

Deux solutions s'offraient alors à moi :

  • Modifier la fonction get_absolute_url définie dans l'application, ce que je ne voulais pas afin de pouvoir suivre les évolutions de Cab
  • Avoir une autre solution.

Pensant que c'était un bug, j'avais remonté l'info à l'auteur de l'application. Ce dernier l'a considéré comme un bug qu'il ne corrigera pas mais m'a dit que je pouvais soit modifier la valeur de la fonction, soit utiliser ABSOLUTE_URL_OVERRIDES.

J'ai donc consulté la documentation sur ABSOLUTE_URL_OVERRIDES. Cela explique qu'on peut simplement modifier la valeur de get_absolute_url en donnant les nouvelles valeurs à utiliser. Génial ! Je rajoute donc dans mon fichier snippets/settings.py :

ABSOLUTE_URL_OVERRIDES = {
    'cab.Language' : lambda o: "/snippets/languages/%s/" % o.slug,
}

Pour rappel, la fonction initale get_absolute_url de ma classe "Language" de l'application cab (ce qui explique le "cab.Language") est :

    def get_absolute_url(self):
        return "/languages/%s/" % self.slug

Suite à ce changement, lorsque j'utilise la fonction get_absolute_url de ma classe Language, je ne suis plus sensé avoir /languages/python mais /snippets/languages/python.

Sauvé ! me dis-je. Et non, raté !

Un petit bug sur la version de développement fait qu'en fait il faut mettre le nom de la classe en minuscule (voir ticket #3646), ce qui me donne donc pour le moment :

ABSOLUTE_URL_OVERRIDES = {
    'cab.language' : lambda o: "/snippets/languages/%s/" % o.slug,
}

Mais bon, maintenant ça marche :-)