J'essaie de request.user pour la méthode propre d'un formulaire, mais comment puis-je accéder à l'objet de demande? Puis-je modifier la méthode de nettoyage pour autoriser l'entrée de variables?
99
La réponse de Ber - la stocker dans des threadlocals - est une très mauvaise idée. Il n'y a absolument aucune raison de le faire de cette façon.
Une bien meilleure façon est de passer outre de la forme __init__
de méthode pour prendre un argument mot - clé supplémentaire, request
. Cela stocke la demande dans le formulaire , où elle est requise et à partir de laquelle vous pouvez y accéder dans votre méthode propre.
class MyForm(forms.Form):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(MyForm, self).__init__(*args, **kwargs)
def clean(self):
... access the request object via self.request ...
et à votre avis:
myform = MyForm(request.POST, request=request)
MISE À JOUR 25/10/2011 : J'utilise maintenant ceci avec une classe créée dynamiquement au lieu d'une méthode, car Django 1.3 affiche une certaine bizarrerie autrement.
Remplacez ensuite
MyCustomForm.__init__
comme suit:Vous pouvez ensuite accéder à l'objet de requête à partir de n'importe quelle méthode de
ModelForm
avecself.request
.la source
__new__
kwargs de la classe qui plus tard sera transmise à la__init__
méthode de la classe . Nommer la classeModelFormWithRequest
je pense que c'est beaucoup plus clair dans sa signification queModelFormMetaClass
.Pour ce que cela vaut, si vous utilisez des vues basées sur des classes , au lieu de vues basées sur des fonctions, remplacez-les
get_form_kwargs
dans votre vue d'édition. Exemple de code pour un CreateView personnalisé :Le code de vue ci-dessus rendra
request
disponible comme l'un des arguments de mot-clé de la__init__
fonction constructeur du formulaire . Par conséquent dans votreModelForm
faire:la source
request
objetget_form_kwargs
automatiquement.self.get_object
? LeCreateView
prolonge leSingleObjectMixin
. Mais si cela fonctionne ou déclenche une exception, cela dépend si vous créez un nouvel objet ou mettez à jour un objet existant; c'est à dire tester les deux cas (et suppression bien sûr).L'approche habituelle est de stocker l'objet de requête dans une référence locale de thread à l'aide d'un middleware. Ensuite, vous pouvez y accéder depuis n'importe où dans votre application, y compris la méthode Form.clean ().
Changer la signature de la méthode Form.clean () signifie que vous avez votre propre version modifiée de Django, ce qui n'est peut-être pas ce que vous voulez.
Merci, le nombre de middleware ressemble à ceci:
Enregistrez ce middleware comme décrit dans la documentation Django
la source
**kwargs
, ce qui signifie que vous devrez transmettre l'objet de requête en tant queMyForm(request.POST, request=request)
.Pour l'administrateur Django, dans Django 1.8
la source
J'ai rencontré ce problème particulier lors de la personnalisation de l'administrateur. Je voulais qu'un certain champ soit validé en fonction des informations d'identification de l'administrateur particulier.
Puisque je ne voulais pas modifier la vue pour transmettre la requête en tant qu'argument au formulaire, voici ce que j'ai fait:
la source
obj=obj
pasobj=None
sur la ligne 11.'function' object has no attribute 'base_fields'
. Cependant, la réponse la plus simple (sans fermeture) @ François fonctionne bien.Vous ne pouvez pas toujours utiliser cette méthode (et c'est probablement une mauvaise pratique), mais si vous n'utilisez le formulaire que dans une vue, vous pouvez l'étendre à l'intérieur de la méthode de vue elle-même.
la source
get_form_class
méthode CBV , si je sais que j'ai besoin de faire beaucoup de choses avec la requête. La création répétée de la classe peut entraîner une surcharge, mais cela ne fait que la déplacer du moment de l'importation au moment de l'exécution.La réponse de Daniel Roseman est toujours la meilleure. Cependant, j'utiliserais le premier argument positionnel pour la requête au lieu de l'argument mot-clé pour plusieurs raisons:
Enfin, j'utiliserais un nom plus unique pour éviter de remplacer une variable existante. Ainsi, ma réponse modifiée ressemble à:
la source
fromage frais du fromager @ pypi: django-requestprovider
la source
J'ai une autre réponse à cette question selon votre condition que vous souhaitez accéder à l'utilisateur dans la méthode propre du formulaire. Vous pouvez essayer ceci. View.py
forms.py
Vous pouvez maintenant accéder à self.instance dans n'importe quelle méthode propre dans form.py
la source
Lorsque vous voulez y accéder via des vues de classe Django "préparées", comme
CreateView
il y a une petite astuce à connaître (= la solution officielle ne fonctionne pas hors de la boîte). Dans le vôtre,CreateView
vous devrez ajouter un code comme celui-ci:= en bref c'est la solution à passer
request
à votre formulaire avec les vues Créer / Mettre à jour de Django.la source