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 ça quoi (et la doc) ?

Deux possibilités pour le trouver, sur sa page github (on regrettera le choix de github et non bitbucket mais bon:) )  ou sur sa page pypi. Ce qui du coup vous permettra de l’installer de deux façon :

  • un petit git clone bien de chez nous
  • un simple : pip install django-ratelimit-backend

La doc est dispo sur la page readthedocs du projet. Et elle est bien fournie. Une aide à l’install, un quickstart et une section pour expliquer comment modifier le critère de limitation et une référence complète du code.

2- Mais au fait, à quoi ça sert ?

A empêcher les vilains méchants pas beau de crier ‘des logins ou un sort’ devant vos jolis sites webs Django. En clair, à ‘bannir’ pendant 5 minutes des IP qui auraient tentées de se logguer sur votre appli à de trop nombreuses reprises.
Les réglages de base sont :

  • si tu tentes de te logguer 30 fois sans y arriver
  • dans une période de moins de 5 minutes
  • alors tu es bannis 5 minutes.

3- Comment ça marche ?

C’est relativement facile.
Première chose, il n’est même pas nécessaire d’ajouter l’app dans vos INSTALLED_APPS, à part si vous voulez lancer les tests (vous pourrez alors installer tox si vous voulez tester avec toutes les versions de django)

Il vous faudra par contre ajouter un backend d’authentification à savoir :  ‘ratelimitbackend.backends.RateLimitModelBackend’.

Il vous faudra de plus :

  • utiliser la vue ratelimitbackend.views.login à la place de django.contrib.auth.views.login
  • si vous utilisez l’admin, utiliser ratelimitbackend. admin au lieu de l’admin normal de django.
  • Ajouter le middleware ratelimitbackend.middleware.RateLimitMiddleware

Vous pourrez bien entendu modifier les critères de détection de vilains. Pour cela il vous suffira d’implémenter votre propre middleware (tout est bien expliqué dans la doc, ne paniquez pas!)

Django-Autocomplete, and all your requests will be complete, but be careful with the horn

Bon, je suis encore en retard pour la django app du mois de juillet, mais je m’améliore, je n’ai plus que 20 jours de retard.

Espérons que la django app du mois d’aout soit à l’heure…. En attendant de voir si en août, à l’heure je serais, je vous propose de découvrir cette petite django-app bien sympatique.

Mais avant un peu de contexte. Je cherche depuis quelques temps une django app pour faire de l’autocompletion. Djangopackages qui est décidément très souvent mon ami propose un tableau récapitulatif assez sympa d’un certain nombre d’app qui propose cela.

Parmi la liste, j’ai décidé de tester django-autocomplete qui me paraissait le mieux répondre à mes besoin, à savoir de l’autocomplete facile coté admin, comme coté site non admin.

Nouveauté ce mois si au niveau du billet, je vais vous présenter deux versions de l’app à savoir la version ‘officielle’ faite par tyrion et un fork fait par etienned. Pourquoi vous présentez deux versions ? Parce que la version d’etienned propose quelques améliorations visuelles intéressantes (et quelques petits refactor pas débiles).

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

Ici cela dépends de la version que vous désirez tester de django-autocomplete. Si vous voulez tester la version première de tyrion alors vous avez  deux possibilité :

  • par un petit hg clone à partir de sa page bitbucket
  • en utilisant easy_install ou pip.

Par contre pour la version d’etienned, pas de package, donc pas d’easy_install ou de pip, il n’y a qu’une solution, un bon vieux hg clone

Chose suffisamment rare pour qu’elle soit mis en avant, il y a une démo de la version première, que vous pourrez tester ici.

Concernant la doc, pour les deux versions, tout se trouve dans bitbucket.

  • Dans la version de tyrion vous aurez droit au fichier Readme et au wiki.
  • Dans la version d’etienned il n’y a que le fichier Readme qui est composé en grande partie du descriptif des addons que propose ce fork (et qui se finit par un exemple d’utilisation dans l’admin).

Est ce que c’est suffisant ? Si vous envisagez de n’utiliser l’autocomplétion que dans la partie admin, clairement oui. Sinon alors là, clairement non. Vraiment pas même. Et à vous les joies de la lecture du code source pour comprendre comment cela fonctionne (ou alors vous pouvez continuer à lire mon billet et voir comment tout cela fonctionne dans la partie 3 🙂 ).

2- Mais au fait, à quoi ça sert ?

Tout simplement à proposer un mécanisme d’autocomplétion sur les champs texte ou Int mais aussi  les foreignkey et les manytomany. Et qui, cerise sur le gâteau, ce veut simple au niveau de son déploiement

Et à le faire d’une façon un peu ‘magique’. On déclare seulement quels sont les models qui mettront en place l’autocomplétion et pour lesquels de leur champs. Et après tout ce fait presque tout seul (en tout cas pour la mise en place des urls qui permettent de retourner le résultat du filtrage en fonction des caractères tapés, c’est tout automatique).

3- Comment ça marche ?

C’est presque tout simple.  En tout cas si vous voulez intégrer django-autcomplete dans l’admin.

Imaginons que vous vouliez autocomplete les auteurs de bouquin dans une app de critique de livre.

Vous allez commencer par déclarer une classe qui configure votre autocomplete :

from autocomplete.views import AutocompleteSettings
class AuthorAutocomplete(AutocompleteSettings):
search_fields = ('^first_name','^last_name')

Ensuite ?

Vous déclarez simplement où vous voulez utiliser votre autocomplete. En partant du principe que votre model pour les reviews de bouquin s’appelle Reviews et que le champ pour l’autheur du bouquin s’appelle book_author cela donnera cela :

from autocomplete.views import autocomplete
autocomplete.register(Reviews.book_author, AuthorAutocomplete)

et voilà. C’est fini. Vous avez dans votre admin, un champ ForeignKey en autocomplétion. Et sans forcer.

En lisant la doc vous verrez que l’on peut faire de façon différente, spécifier le queryset sur lequel on veut limiter l’autocomplete, etc etc …

Maintenant, qu’est ce qui se passe si vous voulez mettre un peu d’autocomplétion dans votre site version pas admin ?

Hum ben là, c’est pas beaucoup plus compliqué en fait. Le problème est juste qu’il n’existe pas de doc.
Mais si vous farfouillez dans le code vous verrez qu’il existe une classe de widget (AutocompleteWidget qui se trouve dans  autocomplete.widgets qui permet de mettre en place l’autocomplétion).

Il vous suffit alors dans votre formulaire, de rajouter le paramêtre widget à votre Field et de lui passer un AutocompleteWidget (qui a lui même en paramètre le champ qui mettra en place l’autocomplétion).

Si l’on reprend l’exemple d’au dessus on pourrait avoir quelque chose ressemblant à cela :

class ReviewForm(forms.ModelForm):
author = forms.ChoiceField(widget=AutocompleteWidget(Review.book_author ))

Il y a bien évidement le widget qui va bien pour la version multiple sélection (MultipleAutocompleteWidget)

Et si l’on continue à fouiller un peu plus, dans utils, on trouvera une très sympathique autocompleteform_factory qui permet de générer un form en prenant un paramètre le Model qui va bien, un dictionnaire listant les champs implémentant l’autocomplétion
ainsi que les champs à exclure.

4 conclusion et tips.

J’ai eu quelques problèmes lors de mes tests lorsque j’ai voulu installer django-autocomplete en temps qu’app dans le répertoire de mon projet et pas dans mon pythonpath. J’avais des phénomènes bizarre de double exécution de code qui me donnais de jolies exception. Je n’ai pas vraiment réussi à comprendre le pourquoi du comment ni pourquoi en sortant simplement l’app du répertoire de mon projet cela se mettait à fonctionner parfaitement…

Pour ceux qui utilisent grappeli, je viens de voir qu’il existait un fork de django-autocomplete pour en faciliter l’intégration. Mais par contre, là, je n’ai pas du tout essayé.

Ha et pour finir, le titre est une référence un peu obscure à un film avec Jack Black:).

Impostor, aucun rapport avec le courrier, la poste ou les gens de petite taille

Avec énormément de retard (non monsieur Daks, je ne vais pas renommer ma rubrique la django app du mois dernier) voici donc la django app du mois de juin.

Ce mois-ci, enfin le mois dernier, je vais vous présenter Impostor une application que j’ai découvert au détour d’un tweet (de dzen je crois )

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

 

Deux possibilité pour le trouver, sa page github ou sa page django packages. Pas de page pypi, enfin pas encore, espérons qu’elle arrive vite.

Pour l’installer, pas le choix, il faut passer par github.
Un petit git clone https://github.com/samastur/Impostor.git et c’est plié.

Quand à la doc, Elle se limite au readme.rst. Mais cela suffit. Et puis le readme est bien clair. Il vous expliquera comment l’installer dans votre projet django et comment vous en servir (et puis si vous continuer à lire, je vous l’expliquerais aussi)

2- Mais au fait, à quoi ça sert ?

 

Tout simplement à se déguiser lorsque l’on se logue. D’ailleurs c’est un des meilleurs noms d’app django que j’ai pu croiser. Décrivant à la fois bien la finalité de l’app tout en étant rigolo.

Impostor vous permettra donc, si vous avez un login staff member de vous loguer en temps qu’un au tre utilisateur. Vous verrez donc l’appli comme il la voit, vous pourrez interagir avec django en étant considéré comme l’utilisateur dont vous avez prit les traits (enfin le login).

3- Comment ça marche ?

C’est tout simple.
Il suffit d’ajouter un backend d’authentification à votre application django, à savoir ‘impostor.backend.AuthBackend’

ce qui doit vous donner quelque chose ressemblant à :

 AUTHENTICATION_BACKENDS = (
 'django.contrib.auth.backends.ModelBackend',
 'impostor.backend.AuthBackend',
 )

et bien entendu il faut ajouter ‘impostor’ à vos INSTALLED_APPS

Ensuite ?

Un simple petit syncdb et c’est fini, vous allez pouvoir vous déguiser en un de vos utilisateurs. Comment ?
Au lieu de vous loguer avec votre login il vous suffira de vous loguer ainsi :

 votrelogin as leloginquevousvoulezdevenir

 

et de taper votre password.

Django-countries ,l’app garantie sans cowboy ni rodéo. djangoApp de mai 1 sur 2

Il va falloir que je me surveille .. parce qu’encore une fois je publie ma django app du mois un peu en retard. Pas grand chose, juste 4 jours.. Mais ça commence comme ça et après on finit par ne plus tenir de rythme du tout.

Du coup, pour marquer, le coup, je publierais deux django app du mois de mai, même si je les publie en juin.

Et pour commencer, django-countries. C’est d’ailleurs assez rigolo parce que je parlais il y a peu de moyen de gérer les pays, avec une liste de choix existantes, etc.. et op, je tombe sur django-countries.

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

Vous trouverez django-countries soit sur sa page pypi soit sur sa page bitbucket.

Pour l’installation, vous avez les trois moyens désormais classique :

  • un easy_install
  • un pip install
  • un bon vieux hg clone

La doc elle se limite à :

  • la page pypi
  • le readme du repository

Sachant que dans les deux cas, le contenu est le même. Mais vu la simplicité de l’app, cela suffit amplement.

2- Mais au fait, à quoi ça sert ?

L’app rajoute tout simplement un nouveau type de field, le CountryField. Ce CountryField vous permettra de gérer les codes à 2 lettres internationaux qui modélisent les pays mais aussi d’afficher un petit gif du drapeau qui va bien.

Et oui, comme dans les vrais sites et tout quoi.

3- Comment ça marche ?

C’est donc vraiment tout couillon. Un field CountryField. Et des instances de fiels qui ont les données membre :

  • code (le code à deux lettres)
  • name (le vrai nom du pays)
  • flag (le chemin vers le drapeau)

Rien de bien compliqué.

Admin django, deux petits tips pour les change_list

L’admin django est vraiment un bonheur pour la productivité. On peut faire plein de choses en moins de temps qu’il n’en faut pour écrire le descriptif des choses en questions.

Après avoir passé quelques heures à farfouiller dans la doc et à faire quelques tests, je me suis dit qu’il n’y avait pas de raisons que je garde mes découvertes pour moi.

Voici donc un premier billet pour partager les plus utiles avec vous.

list_display, comment changer l’entête d’une colonne fonction.

On sait tous comment configurer les colonnes que l’on va afficher dans la vue en liste des content_type. En utilisant list_display. Mais est ce que cela ne vous ai jamais arrivé de vouloir afficher le résultat d’une fonction ?

Aucun problème, il suffit de mettre le nom de la fonction dans list_display. Oui c’est vrai, sauf que.. sauf que l’entête de colonne c’est le nom de la fonction.. Et ça, ce n’est pas très joli.

Sauf que, sauf que django pense à tout. Pour pouvoir afficher un intitulé de colonne sympa au lieu du nom de la fonction, il suffit de rajouter à votre fonction un attribut short_description qui contiendra l’intitulé voulu.

Un petit exemple :

class TestAdmin (admin.ModelAdmin):
    list_display = ('name', 'foo', 'bar', 'super_function')


class Test (model.Models):
    …
    def super_function(self):
        ….
   super_function.short_description =u'mon intitulé de colonne qui tue'

list_display, comment utiliser du HTML dans les colonnes .

De même, il se peut que votre super fonction qui tue, renvoie non pas une valeur simple (genre un nombre) mais du code html (que vous aurez bien entendu généré avec un template). Sauf que là, oh rage, oh désespoir. Vous avez beau faire tout les mark_safe du monde, rien n’y fait. Votre code est escaped…

Comment modifier ça ? La encore, ça passe par un attribut de fonction, allow_tags qu’il vous suffira de mettre à True. Et miracle, ça fonctionne.

Django-extended-choices, l’app qui te donne le choix (mais pas la date)

J’avais plein d’app possible à présenter pour ce billet du mois d’avril. Mais en réfléchissant, je me suis dit que la meilleure app possible à présenter ce moi-si c’était celle qui a été libéré pendant les DjangoCongs à savoir Django-extended-choices.

Et en plus, ce qui est bien, c’est que comme c’est une toute petite app, ça ne sera pas fatiguant du tout d’écrire ce billet.

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

Là c’est tout simple, on la trouve sur github. Et uniquement sur github. Quand à la doc elle tient toute entière dans le fichier Readme.rst qui se trouve lui aussi sur github. (et vous la trouverez aussi en docstring de l’unique classe que contient l’app).

Pour l’installation il suffit ou plutôt il faut forcément, cloner le repo github.

2- Mais au fait, à quoi ça sert ?

A gérer d’une manière propre les Choices que l’on peut avoir à mettre en place dans les fields Django.  Parce qu’il est vrai que la méthode normale, à base de constantes que l’on ne sait pas trop où déclarer et de tuples de tuples, me si elle fonctionne bien, n’est pas super élégante.

L’app permet donc d’encapsuler tout ça dans une belle petite classe

3- Comment ça marche ?

Bon la je vais, sans aucun remords, faire un petit copié/collé de la doc. Parce que l’explication de comment ça marche est très bien faite.

Donc en fait cela marche comme ça :

from extended_choices import Choices

STATES = Choices(
    ('ONLINE',  1, 'Online'),
    ('DRAFT',   2, 'Draft'),
    ('OFFLINE', 3, 'Offline'),
)

class ContentModel(models.Model):
    title      = models.CharField(max_length=255)
    content    = models.TextField()
    state      = models.PositiveSmallIntegerField(choices=STATES.CHOICES, default=STATES.DRAFT)
    related_to = models.ManyToManyField('self', through="ContentToContent", symmetrical=False, blank=True, null=True)

    def __unicode__(self):
        return u'Content "%s" (state=%s)' % (self.title, STATES.CHOICES_DICT[self.state])

    def get_related_content(self):
        return self.related_to.select_related().filter(state=STATES.ONLINE)

plutôt clair non ?

Et cela remplace ce code là :

STATE_ONLINE  = 1
STATE_DRAFT   = 2
STATE_OFFLINE = 3

STATE_CHOICES = (
    (STATE_ONLINE,  'Online'),
    (STATE_DRAFT,   'Draft'),
    (STATE_OFFLINE, 'Offline'),
)

STATE_DICT = dict(STATE_CHOICES)

class ContentModel(models.Model):
    title      = models.CharField(max_length=255)
    content    = models.TextField()
    state      = models.PositiveSmallIntegerField(choices=STATE_CHOICES, default=STATE_DRAFT)
    related_to = models.ManyToManyField('self', through="ContentToContent", symmetrical=False, blank=True, null=True)

    def __unicode__(self):
        return u'Content "%s" (state=%s)' % (self.title, STATE_DICT[self.state])

    def get_related_content(self):
        return self.related_to.select_related().filter(state=STATE_ONLINE)

Personnellement, je trouve que la notation pointée  STATES.CHOICES ou  STATES.DRAFT est bien bien plus clair que la notation précédente.

Conclusion

Une petite app qui ne fait qu’une chose mais qui le fait bien. A utiliser de partout donc. (Il ne manque juste que des tests ..:) ) .

Djangocong 2.0, le bilan

4 jours après la fin des Cong, il est temps pour moi de faire le bilan de cette deuxième est, en tout cas à mon sens, excellente édition.

Les Congs en quelques chiffres :

  • 11 conférences le matin
  • 12 slots de barcamp l’après-midi
  • 1 app releasée durant les Congs
  • 1 doc de bonne pratique lancée
  • 75 personnes le samedi matin dans l’amphi, à écouter les conférences (un peu moins le dimanche matin, après la soirée arrosée, parce que comme là dit un illustre inconnu : ‘ce matin, on a 50% de perte)
  • 3 repas complétement pris en charge par l’organisation
  • un peu plus de 100 dosettes de Senseo utilisés sur les deux jours (mais qu’une dizaine de sachet de thé, on le sait tous, le café est supérieur au thé)
  • 200 litres d’eau bus, au bas mot, parce que dans le sud, il fait chaud, Cong !
  • Quelques bonnes dizaines de coup de soleil, cadeau surprise pour ceux qui n’ont pas l’habitude du vrai soleil du vrai sud.
  • 36 litres de bières (edit : j’avais oublié les 6litres de guinness) et 20 litres de vin bu lors des 6h qu’à durer la soirée du samedi soir. Et pourtant tout le monde est rentré sur ses jambes.
  • Un nombre de kilo de paella engloutis par nos estomacs,  qui fait juste peur. Comme quoi les poneys, ils ont bon appétit.
  • un article dans Linux Magazine dans le prochain numéro.

Les Congs du point de vue d’un organisateur.

La deuxième édition fut l’occasion d’essayer d’être plus pro dans l’organisation des choses. Et je pense qu’on a fait plus qu’essayer.

  • Plus de salles dont un amphi bien équipé niveau son (Merci encore à l’école centrale de Marseille nous avoir accueilli pendant ces deux jours).
  • Plus de préparation au niveau des repas. On a remplacé les réservations dans de multiples restos par des plateaux repas et des sandwitch livrés sur site, pour gagner du temps et permettre de continuer en mangeant les discussions entamées pendant les confs.
  • Une vrai préparation pour la soirée du samedi (à la Boate) et pas juste un ‘on va sur le vieux port et on trouve un resto comme l’année dernière).
  • Quelques choix un peu clivant comme des durées de conf courtes ou du #Nowificonf pendant une partie des Congs.
  • Moins de trajet dans ma voiture pour chercher les gens perdus ou les ramener. Marseille commence à priori à être connu de tous et il n’y a plus de femme enceinte parmi les présentes :).
  • Encore plein de points à parfaire ou à juste faire (comme prévoir l’impression des badges en avance et les donner le premier matin, à l’arrivée. Ou prévoir un vrai carnet de route de l’accompagnant avec activités et truc à faire pour ne pas lâcher les gens comme ça et qu’ils s’ennuient pendant deux jours).

Les congs d’un point de vue perso.

Vivement la troisième édition. Comme les deux premières fois, la fin des Congs arrivant, un grand sentiment de vide se fait sentir et à peine le dimanche soir arrivé, l’envie d’être déjà à l’année prochaine, de pouvoir discuter à nouveau en IRL avec des gens que je ne vois parfois qu’une fois par an.
D’un point de vue perso, l’année dernière avait été une grande claque technique dans ma figure. Deux jours de conférences non stop, ça en met plein les mirettes.
Cette année, malgré le fait qu’il y est moins de conférences ce fut encore mieux. Les confs auxquelles j’ai pu assister m’ont en effet fait découvrir plein d’outil qu’il va falloir que je test, mais les barcamps ont permis d’échanger pour de vrai, de commencer même pour certaines sessions à poser les premières pierres de quelques choses (je pense là a Geek sans Frontière par exemple).

Mais ce n’est pas tout. L’un des points qui fait que cette deuxième édition fut immensément mieux que la première c’est que cette année la partie ‘non technique’ a été pensée et organisée. Et autant sur des découvertes techniques, on peut imaginer les faire par IRC / billets de blog, autant rencontrer les gens et se rendre compte qu’on les apprécie, pour de vrai, hé ben, y a pas à dire, il faut être dans la même pièce.

On mange difficilement de la barbe à papa rose sur IRC. Apprendre le GO, c’est aussi un peu compliqué. Et je ne parlerais même pas de jouer à ‘il était une fois’ avec Kael, Cyberj et Exirel. Ou de tenter de survivre à une partie de Pandémie. Et comme ArmagnacOverIP n’existe pas encore, on a encore besoin que dzen ramène sa bouteille dans son sac pour y gouter (je ne t’oublie pas brutasse, ta chartreuse était très bonne aussi:) ). C’est tout ces moments là. Tout ces moments partagés qui font que pour de vrai, DjangoCong 2.0, putaing, c’était terrible.

Et à l’année prochaine, pour d’autre aventure et une djangoCong 3.0

quelques liens :

 

Petites apps … petites mais costaudes

Pour ce mois de mars, je vais parler non pas d’une seule mais de deux petites apps. Deux apps parce que les apps sont tellement petites que l’on va m’accuser de tirer au flanc si je ne parle que de l’une d’entre elles. Mais que d’un autre cotés, ce n’est pas parce qu’elles sont petites qu’il ne faut pas en parler.

django-generic-aggregation

 

Qui n’a jamais utilisé les agrégat dans Django ? C’est quand même super utile. Et qui n’a pas ralé sur le fait que zut alors… Saperlipopette même, on ne pouvait pas utiliser les agrégat sur les Generic FK ?

Et c’est là qu’arrive django-generic-aggregation. Qui permet justement de le faire.

Concernant l’installation, trois moyens :

Quand à la doc, vous aurez droit à la page de pypi qui est aussi la page de doc de github. Bon après, il faut bien dire que l’app n’est pas super compliqué à comprendre.

Et au pire, il y a le code des tests. Une petite précision toutefois concernant la doc, la page readthedoc de l’app renvoie pour l’instant sur un 404 readthedoc (un 404 en ASCII ART d’ailleurs)

Ensuite à l’utilisation c’est tout simple, un petit exemple, tiré de la doc :

from generic_aggregation import generic_annotate
from django.db.models import Sum, Avg

# assume a Food model and a generic Rating model
apple = Food.objects.create(name='apple')

# create some ratings on the food
Rating.objects.create(content_object=apple, rating=3)
Rating.objects.create(content_object=apple, rating=5)
Rating.objects.create(content_object=apple, rating=7)

>>> aggregate = generic_aggregate(Food.objects.all(), Rating.content_object, Sum('rating'))
>>> print aggregate
15

>>> aggregate = generic_aggregate(Food.objects.all(), Rating.content_object, Avg('rating'))
>>> print aggregate
5

Pour la petite histoire, j’ai découvert cette app en testant django-simple-ratings une autre app du même monsieur.

django-exposure

 

La encore une petite app toute bête qui permet de resizer des images avant de les afficher. Les images redimensionnées sont stockées en mémoire et il y a même une gestion de cache.

La doc est présente sur packages.python.org et elle explique bien la manière de l’utiliser. Après pour vraiment comprendre, vive les sources.

Quand à l’installation, vous pourrez soit utiliser :

un petit pip install django-exposure
ou une récupération d’un tar.gz sur bitbucket
ou même un hg clone

L’utilisation en elle même est très simple. Il suffit en effet d’utiliser le filtre |resize en lui donnant trois paramêtre, Width, Height et Crop.

Crop peut prendre 5 valeurs de 0 à 5 suivant le crop que vous voulez mettre en place ( 0 étant pour un crop centré).

 

Pour rester dans le même sujet, je ne peux finir ce billet sans parler de django-thumbnail-works qui sert comme son nom l’indique à gérer les thumbnail. Le principe étant de là, gérer cela directement au niveau de l’ImageField. Mais je ne peux vous en dire plus, je n’ai pas eu le temps de la tester.

DjangoAstuce : masquer certains champs des settings dans la vue de Debug

Par défaut, la vue de DEBUG affiche toutes les settings. Heureusement pour nous, gentils petits djangonautes, les password des BD mais aussi le password du user emails sont remplacés par des belles petites ***.

 

Mais comment faire pour masquer d’autre champs ? Comme des champs de KEY d’API ou de password divers ? Parce qu’après tout, il peut arriver de devoir en stocker, et de vouloir les cacher à certains des yeux qui pourraient voir la vue de DEBUG.

 

He ben, encore une fois, django a tout prévu. Il suffit en effet que le nom de votre constante contienne soit :

  • SECRET
  • PASSWORD
  • PROFANITIES_LIST
  • SIGNATURE

 

Pour que dans les vues de DEBUG, leur valeur soit remplacé par des ***

 

Et bien entendu, cela marche aussi pour les key des dictionnaires que vous pourriez déclarer dans vos settings (l’exemple parfait étant celui qui sert de configuration pour les BD).

Django-mockups, l’application mi moquette, mi ketchup

Malgré le fait que le mois de février ne fasse que 28 jours, malgré le fait que j’ai maintenant une petiote qui gazouille gentiment en me regardant avec ses grands yeux bleus, malgré le fait que les journées au boulot ne se finissent jamais, même le week-end, je réussi donc la prouesses de sortir à temps la django app du mois de février (et de tenter de vous préparer des petits trucs cools pour ceux qui viendront aux djangocongs, je dis ça, j’en dis pas plus) (et parenthèse bis, je suis très fier de mon titre)

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

Alors on le trouve sur sa page pipy mais aussi sur sa page github.
Pour l’installation, comme souvent on à le choix entre :

  • passer par pip avec un petit pip install django-mockups
  • passer par easy_install
  • passer par un git clone

Quand à la doc, elle est générable quand on installe le paquet sinon la page pipy (mais aussi la home page du projet) en contient une bonne partie. Elle est, en l’état, il faut bien le dire, un peu limité et d’ailleurs l’auteur le dit lui même dans la dernière partie. C’est dommage, mais en attendant une doc plus précise, il y a toujours la possibilité de lire le code.

2- Mais au fait, à quoi ça sert ?

A générer des données. De grosse masse de données de test générées aléatoirement pour remplir vos bases de tests et rendre vos tests plus facile.

3- Comment ça marche ?

En fait on peut utiliser django-mockups de deux façons. Soit en utilisant une ligne de commande soit en mettant un place un script qui va utiliser les classes fourni par l’app et vous permettra de faire bien plus de choses que la simple ligne de commande.
Vous pourrez entre-autre :

  • définir combien de données par modèles vous voulez générer.
  • décider si vous voulez générer ou pas des données de table reliés par fk ou m2m aux tables que vous configurez dans mockups, sachant que bien entendu vous pouvez décider lesquelles des fk vous voulez générer.
  • Pour les m2m, choisir combien de relation vous allez vouloir créer, en pouvant utiliser un intervalle.
  • Spécifier lorsque que vous voulez, au milieu de votre masse de données générées, insérer des données bien précises.

4 Conclusion

Je découvre à peine django-mockup depuis quelques jours. Mais déjà je lui vois de multiples utilisations possibles, que ce soit pour tester des algos de recherche dans une grosse masse de données ou faire des tests de charges plus réalistes qu’auparavant.

Django-admin-tools, la django app de janvier, presque à l’heure

Jusqu’à présent j’avais toujours réussi à poster mes billets de django app à l’heure. Mais là, là, j’ai une excuse. Je suis devenu papa le 31 janvier. Du coup, je n’ai vraiment pas eu le temps pour écrire mon billet de django app (les raleurs qui me diront que j’avais tout les jours d’avant le 31 pour écrire mon billet auront raison.. mais chut, j’ai une excuse, c’est tout).

Ce mois-ci (enfin le mois dernier quoi), je vais parler d’une partie de django dont je ne parle pas assez l’admin, en vous présentant django-admin-tools.

1- Où on le trouve, comment on l’installe, tout ça quoi (et la doc) ?

Où on le trouve sur sa page bitbucket sur laquelle vous trouverez aussi tout plein de screenshoot (que je reproduis ici en partie), une mini doc et un lien vers une doc très très complète.

Quand à l’installation vous pouvez soit :

  • cloner le repo puis faire un python setup.py install
  • utiliser easy install : easy_install django-admin-tools
  • utiliser pip : pip install django-admin-tools
  • simplement mettre le repertoire admin_tools dans votre python path

Quand à la doc, elle est présente sur readthedocs.org et est vraiment très bien faite. bien fournie et claire.

2- Mais au fait, à quoi ça sert ?

Django-admin-tools va vous permettre de customiser votre admin django.

Vous allez pouvoir des petits dasboards en page d’accueil, personnalisable et drag and dropable et foldable. Vous allez aussi pouvoir avoir un menu horizontal et une gestion des bookmarks. Les menus pourront être constitués de sous menus, de liens finaux ou de menus construits automatiquement à partir de  la liste des app (moins celles que l’on décide d’exclure).

3- Comment ça marche ?

Dans tout les cas, il y a une config par défaut. Si on veut changer la config des dashboard ou du menu, il faut générer un module python ( qui par défaut sera celui qui donne la config par défaut), le modifier et indiquer que l’on veut l’utiliser. On peut aussi modifier le thème CSS qui sera utilisé.

Pour le menu :

  • python manage.py custommenu

ou

  • python manage.py custommenu somefile.py

puis :

  • ADMIN_TOOLS_MENU = ‘yourproject.menu.CustomMenu’

pour le dashboard, même chose :

  • python manage.py customdashboard

ou

  • python manage.py customdashboard somefile.py

puis

  • ADMIN_TOOLS_INDEX_DASHBOARD = ‘yourproject.dashboard.CustomIndexDashboard’
  • ADMIN_TOOLS_APP_INDEX_DASHBOARD = ‘yourproject.dashboard.CustomAppIndexDashboard’

4 Conclusion

Je dois bien avouer que je pense sous utilisais l’admin django. Je suis toujours à refaire des trucs en espace non admin alors que l’admin offre pourtant des possibilités immenses, pour très peu de temps passés. La découverte de django-admin-tools me conforte dans l’idée qu’il faut que je me force à utiliser plus souvent l’interface admin. Et donc à tester de nouvelles app d’extension de l’admin.

M2m, tout petite astuce

Il faut parfois utiliser des m2m. Dans django, il y a deux moyens de les utiliser. Soit d’une façon simple, en déclarant juste un ManyToManyField soit en passant par une table explicite grâce à l’argument through.

L’argument through permet d’avoir une table explicitement déclaré que l’on peut donc manipuler avec l’ORM.

Mais si on utilise la méthode commune, celle où c’est django qui fait tout, on pourrait avoir l’impression que l’on a alors, plus accès à cette table de jointure. Ce n’est pas utile allez vous me dire, on s’en fout, la seule info que l’on manque c’est la pk des tuples.

C’est vrai dans la plupart des cas. Mais comment faire si vous veniez à avoir besoin de pouvoir mettre la main sur ces PK ? Si par exemple vous voulez synchroniser des choses ??

Et bien, les choses sont bien faites en django. Il existe en effet une données membres through qui permet de récupérer la table créer automatiquement dans django.

Un petit exemple (en reprenant celui de django)

class Topping(models.Model):
# ...
class Pizza(models.Model):
# ...
    toppings = models.ManyToManyField(Topping)

pour avoir accés à la table qui relie les Pizza au Topping il suffit de faire :

Pizza.toppings.through

et donc pour filter il suffit de faire :

Pizza.toppings.through.objects.filter (…. )

Et voilà.