django-why is the request.POST obiekt niezmienny?
Jak pyta tytuł, dlaczego chłopaki z Django zdecydowali się zaimplementować żądanie.POST obiekt z querydict (co oczywiście z kolei sprawia, że całość jest niezmienna?)
Wiem, że możesz zmutować to wykonując kopię danych posta
post = request.POST.copy()
Ale dlaczego to robisz? Z pewnością byłoby prościej po prostu pozwolić, aby to coś było mutowalne? A może jest używany z jakiegoś innego powodu, który może powodować problemy? 6 answers
To trochę zagadka, prawda? Kilka powierzchownie wiarygodnych teorii okazuje się błędnych w śledztwie: {]}
Aby obiekt
POST
nie musiał implementować metod mutacji? No: obiektPOST
należy dodjango.http.QueryDict
klasa , która implementuje pełny zestaw metod mutacji, w tym__setitem__
,__delitem__
,pop
iclear
. Implementuje niezmienność, sprawdzając flagę podczas wywoływania jednej z metod mutacji. A kiedy wywołujesz metodęcopy
, Pobierz kolejną instancjęQueryDict
z włączoną zmienną flagą.Dla poprawy wydajności? Nie: klasa
QueryDict
nie zyskuje żadnych korzyści z wydajności, gdy zmienna flaga jest wyłączona.Aby obiekt
POST
mógł być użyty jako klucz słownikowy? Nie:QueryDict
obiekty nie są hashowalne.Aby
POST
dane mogły być budowane leniwie (bez konieczności odczytywania całej odpowiedzi), jak tu twierdzisz? Nie widzę na to żadnych dowodów w kod: z tego co wiem, cała odpowiedź jest zawsze czytana, albo bezpośrednio, albo poprzezMultiPartParser
dlamultipart
odpowiedzi.Aby chronić Cię przed błędami programistycznymi? Widziałem to twierdzenie, ale nigdy nie widziałem dobrego wyjaśnienia, czym są te błędy i jak niezmienność chroni przed nimi.
W każdym przypadku POST
jest nie zawsze niezmienne : gdy odpowiedź jest multipart
, to POST
jest zmienna. To wydaje się wykorzystaj większość teorii, które możesz wymyślić. (Chyba, że to zachowanie jest niedopatrzeniem.)
W podsumowaniu, nie widzę jasnego uzasadnienia w Django dla POST
obiektu, który ma być niezmienny dla żądań nie-multipart
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:15
Jeśli żądanie było wynikiem Django form
złożenia, wówczas rozsądne jest, aby POST był immutable
aby zapewnić integralność danych pomiędzy formularzem przekazaniem a formularzem walidacją . Jednakże, jeśli żądanie było a nie wysłane przez Django form
submission, then POST is mutable
ponieważ nie ma walidacji formularza.
Zawsze możesz zrobić coś takiego: (jak na @ leo-the-manic ' s komentarz )
# .....
mutable = request.POST._mutable
request.POST._mutable = True
request.POST['some_data'] = 'test data'
request.POST._mutable = mutable
# ......
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:54
Update :
Gareth Rees miał rację, że pkt 1 i 3 nie były ważne w tym przypadku. Choć myślę, że punkt 2 i 4 są nadal aktualne, dlatego zostawię tutaj tezy.
(zauważyłem, że request.POST
obiekt zarówno Pyramid (Pylon) jak i Django jest jakąś formą MultiDict
. Więc być może jest to bardziej powszechna praktyka niż uczynienie request.POST
niezmiennym.)
Nie mogę mówić za chłopaków z Django, chociaż wydaje mi się, że mogło to być z powodu niektórych z tych uzasadnienie:
-
Performence . obiekty niezmienne są "szybsze" nad zmiennymi, ponieważ pozwalają na znaczne optymalizacje. Obiekt jest niezmienny oznacza, że możemy przeznaczyć dla niego przestrzeń w czasie tworzenia , a wymagania przestrzeni nie ulegają zmianie. Ma również takie rzeczy, jak wydajność kopiowania i wydajność porównywania z tego powodu.Edit : tak nie jest w przypadkuQueryDict
, Jak zauważył Gareth Rees. - W przypadku
request.POST
, to wydaje się, że żadna aktywność po stronie serwera nie powinna zmieniać danych żądania . I dlatego obiekty niezmienne są bardziej odpowiednie, nie wspominając o tym, że mają znaczną przewagę wydajności. -
Obiekty niezmienne mogą być używane jako kluczeEdit : mój błąd, niezmienny nie implikuje bezpośrednio ; hashable obiekty są jednak zazwyczaj niezmienne jak również.dict
, co przypuszczam, że może być bardzo przydatne gdzieś w Django.. - kiedy przekazujesz
request.POST
(zwłaszcza wtyczkom innych firm i wtyczkom), możesz oczekiwać, że ten obiekt żądania od użytkownika pozostanie niezmieniony.
W jakiś sposób te powody są również ogólnymi odpowiedziami na "immutable vs mutable?"pytanie. Jestem pewien, że w przypadku Django jest o wiele więcej rozważań projektowych niż powyżej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-27 15:52:08
Podoba mi się, że domyślnie jest niezmienny. Jak wspomniano, możesz uczynić go zmiennym, jeśli potrzebujesz, ale musisz być o tym szczery. To jest jak " Wiem, że mogę zrobić mój formularz debugowania koszmar, ale wiem, co robię teraz.'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-17 15:24:13
Znalazłem to w komentarzu do Stack Answer https://stackoverflow.com/a/2339963
I musi być niezmienna, aby można było ją budować leniwie. Kopiowanie wymusza uzyskanie wszystkich danych POST. Do momentu otrzymania kopii może nie być ona pobrana. Co więcej, aby wielowątkowy serwer WSGI działał rozsądnie dobrze, pomocne jest, jeśli jest to niezmienne
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:43
Uwaga: multipart
żądania są niezmienne od Django 1.11
https://github.com/django/django/blob/stable/1.11.x/django/http/multipartparser.py#L292
Były mutowalne w poprzednich wersjach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 10:40:07