Comment utiliser proprement un modèle depuis un template

Django

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

Je suis en train de coder un site qui utilise dans son menu un <select> html. Celui-ci doit se remplir en fonction de la BDD mais il apparait sur chaque page de notre site.

Je ne peut donc pas demander a une vue d'envoyer ces données tout le temps et depuis tout les views.py

Comment pourrait-je faire?

Édité par Coyote

J’adorerais changer le monde, mais ils ne veulent pas me fournir le code source…

+0 -0

La solution la plus django-tisante serait d'utiliser un middleware, qui se charge de peupler le contexte des templates avec les bonnes valeurs. Il sera automatiquement appelé à chaque fois.

Sinon, si tu utilise des class-based view, tu peut créer un Mixin qui se charge de faire ça.

Mon Github — Tuto Homebrew — Article Julia

+0 -1
Auteur du sujet

Salut,

Merci de ta réponse. Pour le moment je me suis atteler a une autre partie le temps de trouver un peu chaussure a mon pied, mais pourrait tu m'en dire plus au sujet des middleware? Tu pense a un en particulier ou me serait-ce possible d'en faire moi même?

J’adorerais changer le monde, mais ils ne veulent pas me fournir le code source…

+0 -0

Cette réponse a aidé l'auteur du sujet

En fait je me suis planté, ce ne sont pas les middleware qui te faut mais un context processor. J'ai du mal aujourd'hui …

L'idée est décrite ici, et documentée . En gros c'est une fonction qui prend comme argument la requête et qui renvois un dictionnaire à ajouter au contexte. Du style:

1
2
3
4
5
from .models import MyModel

def my_model_select(request):
    instances = MyModel.objects.all()
    return {"my_model_select": instances}

Et tu ajoute cette fonction dans le réglage qui-va-bien, et paf {{my_model_select}}, tout est accessible dans tous les templates ! Par contre, ça risque de faire plein de requêtes, donc si tu as besoin d'optimiser, tu pourra mettre un cache là dessus.

Édité par Luthaf

Mon Github — Tuto Homebrew — Article Julia

+1 -0
Auteur du sujet

D'après ce que j'ai lu de tes liens ça m'a tout l'air d'être ce que je chercher en vain. Je te donne des nouvelles dès que je le met en place.

Merci pour l'explication en tout cas!

J’adorerais changer le monde, mais ils ne veulent pas me fournir le code source…

+0 -0
Auteur du sujet

Salut,

Je viens de tester ce que j'ai pu voir sur tes liens. Cela a l'air relativement simple mais je me heurte a un petit problème sur la fin. Je ne sais pas quoi faire des dernières directives:

Now when we instantiate a context, we can do it by RequestContext(request, context_dictionary) >instead of Context(context_dictionary).

If you’re using the render_to_response shortcut, just pass it as the context_instance keyword >argument to render_to_response, like so:

return render_to_response("my_app/my_template.html", {'some_var': 'foo'}, context_instance=RequestContext(request))

If you’re using a generic view, you don’t have to do anything except define the >TEMPLATE_CONTEXT_PROCESSORS setting; generic views use RequestContext by default.

And you’re done; now you’ll get your media_url variable available in all of your templates >without having to repetitively call a template tag. app.home.context_processors.py

Il faudrait donc ajouter des directives dans une vue, mais moi je n'en ai pas puisque je veut l'ajouter dans le template principale que j'extends avec tout mes autres templates.

Donc pour l'instant j'ai ceci, qui ne me génère pas d'erreur mais qui ne m'affiche rien.

PS: Sur la fin du post le dernier morceau de code fait tout fonctionner mais ne répond pas vraiment au cahier des charges.

1
2
3
4
5
6
from app.company.models import Company

#For the list of company in the main menu
def company_select(request):
    list_company = Company.objects.all()
    return {"list_company": list_company}

setting.py

1
2
3
4
TEMPLATE_CONTEXT_PROCESSORS = (
   "[...]",
   "app.home.context_processors.company_select",
)

La vue principale

1
2
3
4
{% for company in list_company %}
   <option>ok</option>
   <option>{{ company.name }}</option>
{% endfor %}

PS:

Avec ce rajout ça fonctionne, mais faudrait retoucher alors toutes les vues?

view.py d'une app quelconque

1
2
3
4
from django.template import RequestContext
[...]
def aDef(request):
    return render_to_response([...], context_instance=RequestContext(request))

Édité par Sanoc

J’adorerais changer le monde, mais ils ne veulent pas me fournir le code source…

+0 -0

Cette réponse a aidé l'auteur du sujet

Alors si tu utilise des fonction comme vues, il te faudra en effet les modifier. Par contre, si tu utilise des Class Based-View, ça devrait marcher tout seul :

If you’re using a generic view, you don’t have to do anything except define the TEMPLATE_CONTEXT_PROCESSORS setting; generic views use RequestContext by default.

Mon Github — Tuto Homebrew — Article Julia

+1 -0
Auteur du sujet

D'accord, bon bah c'est l'occasion de passer au vues générique qui apparemment sont plutôt conseiller histoire de pouvoir faire de l’héritage.

J'ai un peu galéré mais je suis arriver a comprendre comment marcher les templateView et ça marche maintenant.

Merci beaucoup pour avoir pris le temps de m'expliquer tout cela!

J’adorerais changer le monde, mais ils ne veulent pas me fournir le code source…

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte