Подтвердить что ты не робот

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 неизменен". Как изменить его?

4b9b3361

Ответ 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, очень простой в использовании. Надеюсь, что поможет