Petites découvertes ou redécouvertes des derniers jours.

 Django  Comments Off on Petites découvertes ou redécouvertes des derniers jours.
Feb 082025
 

Le CSRF , mais pourquoi faire ?

Imaginons, juste comme ça hypothétiquement, que vous vouliez désactiver de manière globale la protection CSRF sur la totalité des urls d’un site django.

Vous pensez qu’il suffit de désactiver le middleware qui va bien (soit django.middleware.csrf.CsrfViewMiddleware ) pour que op c’est bon, la vérification CSRF n’est plus mise en place ?

Vous serez alors décontenancé de voir que non, cela ne suffit pas. Il faut aussi ajouter le décorateur csrf_exempt ( qui se trouve dans django.views.decorators.csrf ) sur chacune de vos urls. Un peu compliqué en vrai, surtout si vous avez beaucoup d’urls. _

Comment faire ?

Tout simplement coder un middleware qui va l’enlever pour vous. Vous n’aurez ensuite qu’à le déclarer dans les middleware actifs.


class NOCSRFMiddleware(object):
def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        setattr(request, '_dont_enforce_csrf_checks', True)
        response = self.get_response(request)
        return response

Et voila ! Il suffit ensuite de le déclarer dans MIDDLEWARE et le tour est joué ( par exemple avec un  BadIdeaApp.BadMiddleware.NOCSRFMiddleware

Groupons, Groupons, Groupons !!!

J’avais totalement oublié l’existence du templatetags regroup qui permet de regrouper des objets identique par un attribut commun. Comme regrouper une liste de dictionnaires par les valeurs de l’un des attributs. La documentation complète est disponible ici : https://docs.djangoproject.com/en/4.2/ref/templates/builtins/#regroup

Et redécouvrir ce templatetags m’a été bien utile. Surtout en le couplant avec un autre templatetags que j’avais également oublié, dicsort ( https://docs.djangoproject.com/fr/4.2/ref/templates/builtins/#std-templatefilter-dictsort) qui va trier une liste de dictionnaire par une des clés des dictionnaires.

 Posted by at 00:41
Jan 052025
 

Je me suis retrouvé il y a quelques temps avec une problématique, remplacer une chaine par une autre dans un attribut CharField d’un model django.

La première possibilité était de faire tout simplement une belle boucle sur la totalité de mes instances de module, faire le remplacement en python et sauvegarder la nouvelle valeur.


Sauf que j’avais quasiment un million d’objet et que je n’avais pas envie que cela prenne des plombes. Et puis c’était un peu moche.

Du coup j’ai un peu fouillé et miracle, j’ai trouvé une solution que voici.

On commence par définir la fonction de remplacement, tout en django et en SQL.


from django.db.models import F, Func, Value
def replace_func(field_name, old_str, replace_str):
    return Func(
        F(field_name),
        Value(old_str), Value(replace_str),
        function='replace'
    )

Ensuite, il n’y a quasiment plus rien à faire. On va simplement appeler update sur tout les objets et utiliser replace_func.

Par exemple :


MonModele.objects.filter(CONDITIONS).update(
    champ_a_modifier=replace_func("champ_a_modifier",
                                  "str_que_lon_veut_remplacer",
                                  "nouvelle_chaine_de_caractere")

Et voila, c’est fini.

 Posted by at 00:55

Configurer les représentations textuelles qui seront utilisées dans les ChoiceField des forms Django.

 Django  Comments Off on Configurer les représentations textuelles qui seront utilisées dans les ChoiceField des forms Django.
Jul 282018
 

Longtemps que je n’avais pas posté de billets dans cette partie du blog. (Vous allez me dire longtemps que je n’ai pas posté de billet tout court, et vous auriez raison, mais ma bonne résolution de fin de vacances d’été est de changer cela).

Mais donc, pour reprendre doucement dans la partie technique, je vais commencer par partager un truc que tout le monde connaît sûrement déjà. Sauf que perso, j’oublie à chaque fois que cette fonctionnalité de django existe et donc je galère pour la retrouver. Du coup je me dis qu’en l’écrivant je finirais par la mémoriser (et donc en fait j’écris plus pour moi qu’autre chose, je suis un vilain !:) ).

Donc imaginons que vous avez un modèle. Truc assez classique. Ce modèle vous lui avez défini une représentation textuelle de base avec str . Sauf que vous avez plusieurs forms, donc certains ont des ChoiceFields utilisant ce modèle (Exemple un modèle User et vous avez un modèle Post où vous devez choisir le rédacteur du billet). Et manque de chance, vous avez besoin d’une représentation textuelle différentes de celle de base pour un de vos forms. Où même pire, vous avez besoin de plusieurs représentations textuelles différentes, pour plein de forms différents.

Vous êtes alors bien marri.

Mais en fait non, parce que Django vous fourni une façon à la fois simple et élégante de faire. A chaque fois que vous aurez besoin d’une représentation textuelle qui ne soit pas celle par défaut, il vous suffira de définir une classe dérivant de ModelChoiceField et qui implémentera la méthode label_from_instance. Cette méthode prend comme unique paramètre l’objet qui doit voir sa représentation textuelle définit et renvoie une chaîne de caractère.

Petit exemple tiré de la doc django :

from django.forms import ModelChoiceField

class MyModelChoiceField(ModelChoiceField):
    def label_from_instance(self, obj):
        return "My Object #%i" % obj.id

Voilà. Aussi simple que cela. Vous n’avez plus qu’à utiliser votre classe fille de ModelChoiceField dans votre formulaire et le tour et joué.

Bonus, ça marche aussi pour les MultipleChoiceField, il faudra simplement définir une classe fille de ModelMultipleChoiceField

et le lien vers la doc qui parle de tout cela : (https://docs.djangoproject.com/fr/2.0/ref/forms/fields/)

 Posted by at 22:22

Django 1.7 et écriture de tests, petites explorations

 Django  Comments Off on Django 1.7 et écriture de tests, petites explorations
Nov 022014
 

Je me suis enfin lancé dans l’écriture d’une app django gérant les badges (ou les succès si vous préférez). L’objectif étant de pouvoir réécrire de zéro histoires de rôlistes. L’idée était de tenter de faire une vraie app django, en mode réutilisable, histoire que peut-être des gens puissent trouver intéressant de l’utiliser.

Je me suis retrouvé avec deux problèmes concernant mes tests :

  • Souvent on gagne un badge quand on a créé suffisamment de chose (comme des checkin, des billets de blogs ou des contributions diverses). Sauf que je ne voulais pas créer dans mon app des models ne servant à rien, juste pour pouvoir en créer lors de mes tests.
  • Je voulais pouvoir créer des badges se gagnant sur un critère du style ‘être venu un certain nombre de fois sur une URL.’ Donc mettre en place des décorateurs sur des vues. Mais là encore, je ne voulais pas avoir à créer des vues dans mon application rien que pour les tests.

Au final, en lisant un peu de doc, j’ai réussi à faire ce que je voulais.

Tester un décorateur sans créer des  vues inutiles dans son app.

Je savais déjà comment forger des requests avec la RequestFactory. Par contre pour créer des vues, je n’en avais pas la moindre idée.. Une petite question plus tard, Foxmask m’a indiqué un lien qui allait me donner la solution que je cherchais. (le voici) Il suffisait au final d’utiliser mock pour créer, directement dans mes tests, une fausse vue que j’allais pouvoir décorer.
Une dernière subtilité, comme vous le verrez dans le lien novapost (ou dans mon code), si vous utilisez wraps pour créer votre décorateur, il faudra ajouter l’argument assigned=available_attrs(view_func) à votre appel à wraps (tout comme django le fait). Cela sera nécessaire pour pouvoir utiliser votre décorateur en mode fonction, ce que vous devrez faire dans vos tests, à cause d’un bug python 2 (celui-ci :http://bugs.python.org/issue3445)

Créer des models uniquement pour les tests

Ici après quelques test infructueux, je suis finalement tombé sur ce ticket dans le track django. Dont le dernier commentaire remonté à 2 mois. Et en fait, l’astuce est toute simple. Il suffit de créer le model de test dans le fichier de test qui va bien (c’est ici au niveau de mon code) et ensuite de modifier manuellement une des migrations django pour ajouter la création du modèle, uniquement si on est dans le mode Test. Petite modification de mon cru comparé au code donné dans le ticket, j’ai fait en sorte que les models de tests soit créé si la base commence par test ou si elle est stockée en mémoire (mon code est ici).

Rien de bien merveilleux ou de bien révolutionnaire, mais bon, on ne sait jamais, ça pourrait peut-être être utile à l’un d’entre vous.

 Posted by at 18:41

DjangoIsland, parce que les poneys savent nager

Vous êtes djangonautes ? Et vous n’avez pas encore acheté votre billet pour DjangoCon Europe ? Alors peut-être que vous ne le saviez pas. Après tout, même si on a essayé de faire un maximum de com sur le sujet, on n’en fait jamais assez et il est fort possible que vous soyez passé à coté. Donc, […]

Les poneys envahissent la ville rose, aka DjangoCon Toulouse, vive les pains aux chocolats !

Ce week-end avait lieu la première DjangoCon Toulouse, une rencontre django régionale au pays du cassoulet. Les festivités commençaient à 11h30 le samedi avec des LT, puis une rafale de huit conférences l’après midi, et pour finir sprint et ateliers le dimanche. Cette Djangocon est également la première Cong qui n’était pas un événement autonome […]

Des poneys avec des chapeaux ronds  aka DjangoBreizh, les poneys envahissent la bretagne

Samedi 17 novembre c’était donc la première edition des DjangoBreizh, une rencontre django locale en bretagne organisé par Exirel (bon ok, je ne suis pas tout a fait breton et pourtant j’y étais mais j’étais une exception) Le programme se découpait ainsi : matin conférence début d’après midi LT reste de l’après midi barcamp ou atelier […]

Orateurs, les rencontres django régionales ont besoin de vous !

L’un des résultats des discussions de la dernière DjangoCong fut de lancer l’idée de faire des DjangoCon régionales plus petites et qui permettraient de ne pas centraliser les attentes de toute la communauté sur un seul événement national. Et du coup d’éviter de générer de la frustration pour ceux qui n’ont pu acheter leurs billets […]

Installation de virtualenvwrapper chez Alwaysdata

J’ai il y a quelques temps fait de multiples tests chez AD. Certains nécessitaient l’utilisation de paquet python non installé par défaut sur le serveur mutu AD. Du coup, j’ai voulu installer virtualenwrapper pour me simplifier la tache. Voici la méthode que j’ai utilisé. Je suis preneur de toute amélioration que vous pourriez me remonter […]

Pony rider in the skyyyy… c’est le retour des djangocong YeeHa !!

Je vous préviens, tout de suite, j’aurais pu céder à la facilité et parsemer mon billet d’annonce d’image de petit poney rose, pour coller aux thèmes du poney, de django, de l’amour platonique qui anime tout ceux qui font du django ( #sharethelove nan ?? ha non pardon c’est pas la bonne conférence). Mais non, je […]

Django-ratelimit-backend ne réglera pas vos problèmes de foie, mais de rate oui…

Deuxième édition de la django app du mois précédent, encore une fois sur le fil, alors que les citrouilles continuent à ricaner dans leurs coins. Ce mois-ci c’est django-ratelimit-backend, une des multiples apps de monsieur Brutasse (qui ne doit jamais dormir pour publier autant de truc…) 1- Où on le trouve, comment on l’installe, tout […]