Django, изменяющий объект запроса
У меня уже есть проект django, и он логичен, например:
url: URL? username = name & pwd = passwd
Вид:
def func(request):
dic = request.GET
username = dic.get("username")
pwd = dic.get("pwd")
но теперь нам нужно зашифровать данные. Затем запрос станет следующим:
url: URL? crypt = XXXXXXXXXX (XXXXXXXX зашифрован str для "username = name & pwd = passwd" )
поэтому мне нужно изменить каждую функцию представления. Но теперь я хочу дешифровать в промежуточном программном обеспечении django, чтобы предотвратить изменение каждой функции представления.
но когда я изменяю request.GET, я получаю сообщение об ошибке msg "Этот экземпляр QueryDict неизменен". Как изменить его?
Ответы
Ответ 1
django.http.QueryDict
объекты, которые назначены request.GET
и request.POST
, неизменяемы.
Вы можете преобразовать его в изменяемый экземпляр QueryDict
, скопировав его:
request.GET = request.GET.copy()
После этого вы сможете изменить QueryDict
:
>>> from django.test.client import RequestFactory
>>> request = RequestFactory().get('/')
>>> request.GET
<QueryDict: {}>
>>> request.GET['foo'] = 'bar'
AttributeError: This QueryDict instance is immutable
>>> request.GET = request.GET.copy()
<QueryDict: {}>
>>> request.GET['foo'] = 'bar'
>>> request.GET
<QueryDict: {'foo': 'bar'}>
Это целенаправленно спроектировано таким образом, что ни одному из компонентов приложения не разрешено редактировать данные запроса источника, поэтому даже создание неизменяемого QueryDict
снова нарушит этот дизайн. Я бы по-прежнему предлагал вам следовать рекомендациям и назначать дополнительные данные запроса непосредственно на объект request
в вашем промежуточном программном обеспечении, несмотря на то, что он может заставить вас редактировать ваши источники.
Ответ 2
Удалить неизменяемость:
if not request.GET._mutable:
request.GET._mutable = True
# now you can spoil it
request.GET['pwd'] = 'iloveyou'
Ответ 3
Вы не должны использовать GET для отправки имени пользователя и пароля, это плохая практика (поскольку она отображает информацию о панели URL и может представлять угрозу безопасности ). Вместо этого используйте POST. Кроме того, я предполагаю, что вы пытаетесь аутентифицировать своих пользователей, и кажется, что вы делаете слишком много работы (создаете новое промежуточное ПО), чтобы иметь дело с чем-то, что полностью встроено, чтобы взять пример из документации:
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# Redirect to a success page.
else:
# Return a 'disabled account' error message
else:
# Return an 'invalid login' error message.
Мне очень нравится использовать login_required decorator, очень простой в использовании. Надеюсь, что поможет