Ich versuche, request.user für die Bereinigungsmethode eines Formulars anzufordern, aber wie kann ich auf das Anforderungsobjekt zugreifen? Kann ich die Bereinigungsmethode so ändern, dass Variablen eingegeben werden können?
99
Die Antwort von Ber - es in Threadlocals zu speichern - ist eine sehr schlechte Idee. Es gibt absolut keinen Grund, dies so zu tun.
Eine viel bessere Möglichkeit besteht darin, die __init__
Methode des Formulars zu überschreiben , um ein zusätzliches Schlüsselwortargument zu verwenden request
. Dadurch wird die Anforderung im Formular gespeichert , wo sie benötigt wird und von wo aus Sie mit Ihrer Bereinigungsmethode darauf zugreifen können.
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 ...
und aus Ihrer Sicht:
myform = MyForm(request.POST, request=request)
AKTUALISIERT am 25.10.2011 : Ich verwende dies jetzt mit einer dynamisch erstellten Klasse anstelle einer Methode, da Django 1.3 ansonsten etwas seltsam ist.
Dann überschreiben Sie
MyCustomForm.__init__
wie folgt:Sie können dann von einer beliebigen Methode
ModelForm
mit auf das Anforderungsobjekt zugreifenself.request
.quelle
__new__
kwargs eine Anfrage hinzu, die später an die__init__
Methode der Klasse übergeben wird.ModelFormWithRequest
Ich nenne die Klasse viel klarer in ihrer Bedeutung alsModelFormMetaClass
.Wenn Sie klassenbasierte Ansichten anstelle von funktionsbasierten Ansichten verwenden, überschreiben Sie diese
get_form_kwargs
in Ihrer Bearbeitungsansicht. Beispielcode für eine benutzerdefinierte CreateView :Der obige Ansichtscode wird
request
als eines der Schlüsselwortargumente für die__init__
Konstruktorfunktion des Formulars verfügbar gemacht . Deshalb in IhremModelForm
do:quelle
request
Objektget_form_kwargs
automatisch enthalten ist.self.get_object
? DasCreateView
erweitert dieSingleObjectMixin
. Ob dies funktioniert oder eine Ausnahme auslöst, hängt davon ab, ob Sie ein neues Objekt erstellen oder ein vorhandenes aktualisieren. dh beide Fälle testen (und natürlich löschen).Der übliche Ansatz besteht darin, das Anforderungsobjekt mithilfe einer Middleware in einer threadlokalen Referenz zu speichern. Dann können Sie von überall in Ihrer App darauf zugreifen, einschließlich der Form.clean () -Methode.
Wenn Sie die Signatur der Form.clean () -Methode ändern, haben Sie eine eigene, geänderte Version von Django, die möglicherweise nicht Ihren Wünschen entspricht.
Vielen Dank, dass die Anzahl der Middleware ungefähr so aussieht:
Registrieren Sie diese Middleware wie in den Django-Dokumenten beschrieben
quelle
**kwargs
bedeutet, dass Sie das Anforderungsobjekt als übergeben müssenMyForm(request.POST, request=request)
.Für Django-Administrator in Django 1.8
quelle
Ich bin beim Anpassen des Administrators auf dieses spezielle Problem gestoßen. Ich wollte, dass ein bestimmtes Feld basierend auf den Anmeldeinformationen des jeweiligen Administrators überprüft wird.
Da ich die Ansicht nicht ändern wollte, um die Anforderung als Argument an das Formular zu übergeben, habe ich Folgendes getan:
quelle
obj=obj
nichtobj=None
in Zeile 11.'function' object has no attribute 'base_fields'
. Die einfachere (ohne Abschluss) @ François-Antwort funktioniert jedoch reibungslos.Sie können diese Methode nicht immer verwenden (und es ist wahrscheinlich eine schlechte Vorgehensweise), aber wenn Sie das Formular nur in einer Ansicht verwenden, können Sie es innerhalb der Ansichtsmethode selbst erfassen.
quelle
get_form_class
Methode, wenn ich weiß, dass ich mit der Anfrage viele Dinge tun muss. Das wiederholte Erstellen der Klasse kann mit einem gewissen Aufwand verbunden sein, der jedoch nur von der Importzeit zur Laufzeit verschoben wird.Die Antwort von Daniel Roseman ist immer noch die beste. Ich würde jedoch aus einigen Gründen das erste Positionsargument für die Anforderung anstelle des Schlüsselwortarguments verwenden:
Zuletzt würde ich einen eindeutigeren Namen verwenden, um zu vermeiden, dass eine vorhandene Variable überschrieben wird. Meine modifizierte Antwort sieht also so aus:
quelle
Frischkäse von Cheesebaker @ Pypi: Django-Requestprovider
quelle
Ich habe eine andere Antwort auf diese Frage gemäß Ihrer Anforderung, dass Sie auf den Benutzer über die saubere Methode des Formulars zugreifen möchten. Sie können dies versuchen. View.py
forms.py
Jetzt können Sie in jeder sauberen Methode in form.py auf die self.instance zugreifen
quelle
Wenn Sie über "vorbereitete" Django-Klassenansichten darauf zugreifen möchten,
CreateView
ist ein kleiner Trick zu kennen (= die offizielle Lösung funktioniert nicht sofort). In Ihrem eigenen müssenCreateView
Sie Code wie folgt hinzufügen:= Kurz gesagt, dies ist die Lösung, die
request
Sie mit den Ansichten "Erstellen / Aktualisieren" von Django an Ihr Formular übergeben können.quelle