Próbuję request.user dla czystej metody formularza, ale jak mogę uzyskać dostęp do obiektu żądania? Czy mogę zmodyfikować metodę czyszczenia, aby umożliwić wprowadzanie zmiennych?
99
Odpowiedź Bera - przechowywanie jej w „Threadlocals” - to bardzo zły pomysł. Nie ma absolutnie żadnego powodu, aby to robić w ten sposób.
Dużo lepszym sposobem jest przesłonić formie za __init__
metodę do podjęcia dodatkowego argumentu słowa kluczowego request
. Spowoduje to zapisanie żądania w formularzu tam, gdzie jest to wymagane i skąd możesz uzyskać do niego dostęp w swojej czystej metodzie.
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 ...
i Twoim zdaniem:
myform = MyForm(request.POST, request=request)
ZAKTUALIZOWANO 25.10.2011 : Teraz używam tego z dynamicznie tworzoną klasą zamiast metody, ponieważ w przeciwnym razie Django 1.3 wyświetla pewne dziwactwa.
Następnie nadpisz
MyCustomForm.__init__
w następujący sposób:Następnie możesz uzyskać dostęp do obiektu żądania z dowolnej metody
ModelForm
withself.request
.źródło
__new__
przesłonięcie , dodajesz żądanie do kwargs, które później zostaną przekazane do metody klasy__init__
. Nazwanie klasyModelFormWithRequest
wydaje mi się o wiele jaśniejsze w tym znaczeniu niżModelFormMetaClass
.Co jest warte, jeśli używasz widoków opartych na klasach , zamiast widoków opartych na funkcjach, nadpisz
get_form_kwargs
w widoku do edycji. Przykładowy kod dla niestandardowego CreateView :Powyższy kod widoku będzie
request
dostępny jako jeden z argumentów słów kluczowych__init__
funkcji konstruktora formularza . Dlatego w twoimModelForm
:źródło
request
obiektu wget_form_kwargs
środku.self.get_object
?CreateView
RozszerzaSingleObjectMixin
. Ale to, czy to zadziała, czy zgłosi wyjątek, zależy od tego, czy tworzysz nowy obiekt, czy aktualizujesz istniejący; tzn. przetestuj oba przypadki (i oczywiście usuń).Typowym podejściem jest przechowywanie obiektu żądania w odwołaniu lokalnym wątku przy użyciu oprogramowania pośredniczącego. Następnie możesz uzyskać do niego dostęp z dowolnego miejsca w aplikacji, w tym z metody Form.clean ().
Zmiana sygnatury metody Form.clean () oznacza, że masz własną, zmodyfikowaną wersję Django, która może nie być tym, czego chcesz.
Dziękuję, liczba oprogramowania pośredniego wygląda mniej więcej tak:
Zarejestruj to oprogramowanie pośredniczące zgodnie z opisem w dokumentacji Django
źródło
**kwargs
, co oznacza, że będziesz musiał przekazać obiekt żądania jakoMyForm(request.POST, request=request)
.Dla administratora Django, w Django 1.8
źródło
Napotkałem ten konkretny problem podczas dostosowywania administratora. Chciałem, aby pewne pole zostało zweryfikowane na podstawie danych uwierzytelniających konkretnego administratora.
Ponieważ nie chciałem modyfikować widoku, aby przekazać żądanie jako argument do formularza, wykonałem następujące czynności:
źródło
obj=obj
nieobj=None
w linii 11.'function' object has no attribute 'base_fields'
. Jednak prostsza (bez zamknięcia) odpowiedź @ François działa płynnie.Nie zawsze możesz użyć tej metody (i jest to prawdopodobnie zła praktyka), ale jeśli używasz formularza tylko w jednym widoku, możesz określić zakres wewnątrz samej metody widoku.
źródło
get_form_class
metodą CBV , jeśli wiem, że muszę zrobić wiele rzeczy z żądaniem. Wielokrotne tworzenie klasy może wiązać się z pewnym narzutem, ale to po prostu przenosi ją z czasu importu do czasu wykonywania.Odpowiedź Daniela Rosemana jest nadal najlepsza. Jednak użyłbym pierwszego argumentu pozycyjnego dla żądania zamiast argumentu słowa kluczowego z kilku powodów:
Na koniec użyłbym bardziej unikalnej nazwy, aby uniknąć zastępowania istniejącej zmiennej. Tak więc Moja zmodyfikowana odpowiedź wygląda następująco:
źródło
świeży ser od cheesebaker @ pypi: django-requestprovider
źródło
Mam inną odpowiedź na to pytanie, zgodnie z twoim wymaganiem, aby uzyskać dostęp do użytkownika do czystej metody formularza. Możesz tego spróbować. View.py
forms.py
Teraz możesz uzyskać dostęp do self.instance w dowolnej czystej metodzie w form.py
źródło
Kiedy chcesz uzyskać do niego dostęp przez „przygotowane” widoki klas Django,
CreateView
to jest taka mała sztuczka, którą trzeba znać (= oficjalne rozwiązanie nie działa po wyjęciu z pudełka). W swoim własnymCreateView
będziesz musiał dodać taki kod:= w skrócie jest to rozwiązanie, które należy przekazać
request
do formularza z widokami tworzenia / aktualizacji Django.źródło