{"id":1598,"date":"2011-08-20T01:33:26","date_gmt":"2011-08-19T23:33:26","guid":{"rendered":"http:\/\/j-mad.com\/blog\/?p=1598"},"modified":"2011-09-24T21:02:51","modified_gmt":"2011-09-24T19:02:51","slug":"django-autocomplete-and-all-your-requests-will-be-complete-but-be-careful-with-the-horn","status":"publish","type":"post","link":"https:\/\/j-mad.com\/blog\/2011\/08\/20\/django-autocomplete-and-all-your-requests-will-be-complete-but-be-careful-with-the-horn\/","title":{"rendered":"Django-Autocomplete, and all your requests will be complete, but  be careful with the horn"},"content":{"rendered":"<p>Bon, je suis encore en retard pour la django app du mois de juillet, mais je m&#8217;am\u00e9liore, je n&#8217;ai plus que 20 jours de retard.<\/p>\n<p>Esp\u00e9rons que la django app du mois d&#8217;aout soit \u00e0 l&#8217;heure&#8230;. En attendant de voir si en ao\u00fbt, \u00e0 l&#8217;heure je serais, je vous propose de d\u00e9couvrir cette petite django-app bien sympatique.<\/p>\n<p>Mais avant un peu de contexte. Je cherche depuis quelques temps une django app pour faire de l&#8217;autocompletion. <a href=\"http:\/\/djangopackages.com\" target=\"_blank\">Djangopackages<\/a> qui est d\u00e9cid\u00e9ment tr\u00e8s souvent mon ami propose un <a href=\"http:\/\/djangopackages.com\/grids\/g\/auto-complete\/\" target=\"_blank\">tableau r\u00e9capitulatif assez sympa d&#8217;un certain nombre d&#8217;app qui propose cela<\/a>.<\/p>\n<p>Parmi la liste, j&#8217;ai d\u00e9cid\u00e9 de tester <a href=\"https:\/\/bitbucket.org\/tyrion\/django-autocomplete\" target=\"_blank\">django-autocomplete<\/a> qui me paraissait le mieux r\u00e9pondre \u00e0 mes besoin, \u00e0 savoir de l&#8217;autocomplete facile cot\u00e9 admin, comme cot\u00e9 site non admin.<\/p>\n<p>Nouveaut\u00e9 ce mois si au niveau du billet, je vais vous pr\u00e9senter deux versions de l&#8217;app \u00e0 savoir la <a href=\"https:\/\/bitbucket.org\/tyrion\/django-autocomplete\" target=\"_blank\">version &#8216;officielle&#8217; faite par tyrion<\/a> et un <a href=\"https:\/\/bitbucket.org\/etienned\/django-autocomplete\" target=\"_blank\">fork fait par etienned<\/a>. Pourquoi vous pr\u00e9sentez deux versions&nbsp;? Parce que la version d&#8217;etienned propose quelques am\u00e9liorations visuelles int\u00e9ressantes (et quelques petits refactor pas d\u00e9biles).<\/p>\n<h1>1- O\u00f9 on le trouve, comment on l\u2019installe, tout \u00e7a quoi (et la doc)&nbsp;?<\/h1>\n<p>Ici cela d\u00e9pends de la version que vous d\u00e9sirez tester de django-autocomplete. Si vous voulez tester la <a href=\"https:\/\/bitbucket.org\/tyrion\/django-autocomplete\" target=\"_blank\">version premi\u00e8re de tyrion<\/a> alors vous avez&nbsp; deux possibilit\u00e9&nbsp;:<\/p>\n<ul>\n<li>par un petit hg clone \u00e0 partir de sa page bitbucket<\/li>\n<li>en utilisant easy_install ou pip.<\/li>\n<\/ul>\n<p>Par contre pour la version <a href=\"https:\/\/bitbucket.org\/etienned\/django-autocomplete\" target=\"_blank\">d&#8217;etienned<\/a>, pas de package, donc pas d&#8217;easy_install ou de pip, il n&#8217;y a qu&#8217;une solution, un bon vieux hg clone<\/p>\n<p>Chose suffisamment rare pour qu&#8217;elle soit mis en avant, il y a une d\u00e9mo de la version premi\u00e8re, que vous pourrez tester <a href=\"http:\/\/autocomplete.ep.io\/example\/\" target=\"_blank\">ici<\/a>.<\/p>\n<p>Concernant la doc, pour les deux versions, tout se trouve dans bitbucket.<\/p>\n<ul>\n<li>Dans la version de tyrion vous aurez droit au fichier <a href=\"https:\/\/bitbucket.org\/tyrion\/django-autocomplete\/src\/fef4e822ff0f\/README.rst\" target=\"_blank\">Readme<\/a> et au <a href=\"https:\/\/bitbucket.org\/tyrion\/django-autocomplete\/wiki\/Home\" target=\"_blank\">wiki<\/a>.<\/li>\n<li>Dans la version d&#8217;etienned il n&#8217;y a que le fichier Readme qui est compos\u00e9 en grande partie du descriptif des addons que propose ce fork (et qui se finit par un exemple d&#8217;utilisation dans l&#8217;admin).<\/li>\n<\/ul>\n<p>Est ce que c&#8217;est suffisant&nbsp;? Si vous envisagez de n&#8217;utiliser l&#8217;autocompl\u00e9tion que dans la partie admin, clairement oui. Sinon alors l\u00e0, clairement non. Vraiment pas m\u00eame. Et \u00e0 vous les joies de la lecture du code source pour comprendre comment cela fonctionne (ou alors vous pouvez continuer \u00e0 lire mon billet et voir comment tout cela fonctionne dans la partie 3 \ud83d\ude42 ).<\/p>\n<h1>2- Mais au fait, \u00e0 quoi \u00e7a sert&nbsp;?<\/h1>\n<p>Tout simplement \u00e0 proposer un m\u00e9canisme d&#8217;autocompl\u00e9tion sur les champs texte ou Int mais aussi&nbsp; les foreignkey et les manytomany. Et qui, cerise sur le g\u00e2teau, ce veut simple au niveau de son d\u00e9ploiement<\/p>\n<p>Et \u00e0 le faire d&#8217;une fa\u00e7on un peu &#8216;magique&#8217;. On d\u00e9clare seulement quels sont les models qui mettront en place l&#8217;autocompl\u00e9tion et pour lesquels de leur champs. Et apr\u00e8s tout ce fait presque tout seul (en tout cas pour la mise en place des urls qui permettent de retourner le r\u00e9sultat du filtrage en fonction des caract\u00e8res tap\u00e9s, c&#8217;est tout automatique).<\/p>\n<h1>3- Comment \u00e7a marche&nbsp;?<\/h1>\n<p>C&#8217;est presque tout simple.&nbsp; En tout cas si vous voulez int\u00e9grer django-autcomplete dans l&#8217;admin.<\/p>\n<p>Imaginons que vous vouliez autocomplete les auteurs de bouquin dans une app de critique de livre.<\/p>\n<p>Vous allez commencer par d\u00e9clarer une classe qui configure votre autocomplete&nbsp;:<\/p>\n<div class=\"codecolorer-container python default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><div class=\"python codecolorer\"><span class=\"kw1\">from<\/span> autocomplete.<span class=\"me1\">views<\/span> <span class=\"kw1\">import<\/span> AutocompleteSettings<br \/>\n<span class=\"kw1\">class<\/span> AuthorAutocomplete<span class=\"br0\">&#40;<\/span>AutocompleteSettings<span class=\"br0\">&#41;<\/span>:<br \/>\nsearch_fields <span class=\"sy0\">=<\/span> <span class=\"br0\">&#40;<\/span><span class=\"st0\">'^first_name'<\/span><span class=\"sy0\">,<\/span><span class=\"st0\">'^last_name'<\/span><span class=\"br0\">&#41;<\/span><\/div><\/div>\n<p>Ensuite&nbsp;?<\/p>\n<p>Vous d\u00e9clarez simplement o\u00f9 vous voulez utiliser votre autocomplete. En partant du principe que votre model pour les reviews de bouquin s&#8217;appelle Reviews et que le champ pour l&#8217;autheur du bouquin s&#8217;appelle book_author cela donnera cela&nbsp;:<\/p>\n<div class=\"codecolorer-container python default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><div class=\"python codecolorer\"><span class=\"kw1\">from<\/span> autocomplete.<span class=\"me1\">views<\/span> <span class=\"kw1\">import<\/span> autocomplete<br \/>\nautocomplete.<span class=\"me1\">register<\/span><span class=\"br0\">&#40;<\/span>Reviews.<span class=\"me1\">book_author<\/span><span class=\"sy0\">,<\/span> AuthorAutocomplete<span class=\"br0\">&#41;<\/span><\/div><\/div>\n<p>et voil\u00e0. C&#8217;est fini. Vous avez dans votre admin, un champ ForeignKey en autocompl\u00e9tion. Et sans forcer.<\/p>\n<p>En lisant la doc vous verrez que l&#8217;on peut faire de fa\u00e7on diff\u00e9rente, sp\u00e9cifier le queryset sur lequel on veut limiter l&#8217;autocomplete, etc etc \u2026<\/p>\n<p>Maintenant, qu&#8217;est ce qui se passe si vous voulez mettre un peu d&#8217;autocompl\u00e9tion dans votre site version pas admin&nbsp;?<\/p>\n<p>Hum ben l\u00e0, c&#8217;est pas beaucoup plus compliqu\u00e9 en fait. Le probl\u00e8me est juste qu&#8217;il n&#8217;existe pas de doc.<br \/>\nMais si vous farfouillez dans le code vous verrez qu&#8217;il existe une classe de widget (AutocompleteWidget qui se trouve dans&nbsp; autocomplete.widgets qui permet de mettre en place l&#8217;autocompl\u00e9tion).<\/p>\n<p>Il vous suffit alors dans votre formulaire, de rajouter le param\u00eatre widget \u00e0 votre Field et de lui passer un AutocompleteWidget (qui a lui m\u00eame en param\u00e8tre le champ qui mettra en place l&#8217;autocompl\u00e9tion).<\/p>\n<p>Si l&#8217;on reprend l&#8217;exemple d&#8217;au dessus on pourrait avoir quelque chose ressemblant \u00e0 cela&nbsp;:<\/p>\n<div class=\"codecolorer-container python default\" style=\"overflow:auto;white-space:nowrap;width:90%;\"><div class=\"python codecolorer\"><span class=\"kw1\">class<\/span> ReviewForm<span class=\"br0\">&#40;<\/span>forms.<span class=\"me1\">ModelForm<\/span><span class=\"br0\">&#41;<\/span>:<br \/>\nauthor <span class=\"sy0\">=<\/span> forms.<span class=\"me1\">ChoiceField<\/span><span class=\"br0\">&#40;<\/span>widget<span class=\"sy0\">=<\/span>AutocompleteWidget<span class=\"br0\">&#40;<\/span>Review.<span class=\"me1\">book_author<\/span> <span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><\/div><\/div>\n<p>Il y a bien \u00e9videment le widget qui va bien pour la version multiple s\u00e9lection (MultipleAutocompleteWidget)<\/p>\n<p>Et si l&#8217;on continue \u00e0 fouiller un peu plus, dans utils, on trouvera une tr\u00e8s sympathique autocompleteform_factory qui permet de g\u00e9n\u00e9rer un form en prenant un param\u00e8tre le Model qui va bien, un dictionnaire listant les champs impl\u00e9mentant l&#8217;autocompl\u00e9tion<br \/>\nainsi que les champs \u00e0 exclure.<\/p>\n<h1>4 conclusion et tips.<\/h1>\n<p>J&#8217;ai eu quelques probl\u00e8mes lors de mes tests lorsque j&#8217;ai voulu installer django-autocomplete en temps qu&#8217;app dans le r\u00e9pertoire de mon projet et pas dans mon pythonpath. J&#8217;avais des ph\u00e9nom\u00e8nes bizarre de double ex\u00e9cution de code qui me donnais de jolies exception. Je n&#8217;ai pas vraiment r\u00e9ussi \u00e0 comprendre le pourquoi du comment ni pourquoi en sortant simplement l&#8217;app du r\u00e9pertoire de mon projet cela se mettait \u00e0 fonctionner parfaitement&#8230;<\/p>\n<p>Pour ceux qui utilisent grappeli, je viens de voir qu&#8217;il existait un fork de<a href=\"https:\/\/bitbucket.org\/dwaiter\/django-autocomplete-grappelli\" target=\"_blank\"> django-autocomplete<\/a> pour en faciliter l&#8217;int\u00e9gration. Mais par contre, l\u00e0, je n&#8217;ai pas du tout essay\u00e9.<\/p>\n<p>Ha et pour finir, le titre est une r\u00e9f\u00e9rence un peu obscure \u00e0 un film avec Jack Black:).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Bon, je suis encore en retard pour la django app du mois de juillet, mais je m&#8217;am\u00e9liore, je n&#8217;ai plus que 20 jours de retard. Esp\u00e9rons que la django app du mois d&#8217;aout soit \u00e0 l&#8217;heure&#8230;. En attendant de voir si en ao\u00fbt, \u00e0 l&#8217;heure je serais, je vous propose de d\u00e9couvrir cette petite django-app &hellip; <a href=\"https:\/\/j-mad.com\/blog\/2011\/08\/20\/django-autocomplete-and-all-your-requests-will-be-complete-but-be-careful-with-the-horn\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Django-Autocomplete, and all your requests will be complete, but  be careful with the horn<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[35],"tags":[99,98],"class_list":["post-1598","post","type-post","status-publish","format-standard","hentry","category-la-django-app-du-mois","tag-django","tag-python"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p12cdp-pM","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/posts\/1598","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/comments?post=1598"}],"version-history":[{"count":9,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/posts\/1598\/revisions"}],"predecessor-version":[{"id":1690,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/posts\/1598\/revisions\/1690"}],"wp:attachment":[{"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/media?parent=1598"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/categories?post=1598"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/j-mad.com\/blog\/wp-json\/wp\/v2\/tags?post=1598"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}