web-dev-qa-db-fra.com

django modifiant l'objet de requête

J'ai déjà un projet Django et c'est logique comme ceux-ci:

url: URL? nomutilisateur = nom & pwd = motdepasse

vue:

def func(request):
   dic = request.GET

   username = dic.get("username")
   pwd = dic.get("pwd")

mais maintenant nous avons besoin de chiffrer les données. Ensuite, la demande devient ceci:

url: URL? crypt = XXXXXXXXXX (XXXXXXXX est une chaîne chiffrée pour "nom_utilisateur = nom & pwd = motdepasse")

j'ai donc besoin de modifier chaque fonction de vue. Mais maintenant, je veux déchiffrer le middleware Django) pour empêcher de modifier toutes les fonctions d'affichage.

mais quand je modifie request.GET, je reçois un message d'erreur "Cette instance de QueryDict est immuable". Comment puis-je le modifier?

50
user2801567

Django.http.QueryDict objets assignés à request.GET et request.POST sont immuables.

Vous pouvez le convertir en une instance mutable QueryDict en le copiant:

request.GET = request.GET.copy()

Ensuite, vous pourrez modifier le 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'}>

Cela a été délibérément conçu pour qu'aucun des composants de l'application ne soit autorisé à modifier les données de la demande source. Par conséquent, même la création d'un QueryDict immuable à nouveau romprait cette conception. Je suggérerais néanmoins que vous suiviez les instructions et attribuiez des données de demande supplémentaires directement sur l'objet request de votre middleware, malgré le fait que cela pourrait vous amener à modifier vos sources.

85
Filip Dupanović

Supprimer l'immutabilité:

if not request.GET._mutable:
   request.GET._mutable = True

# now you can spoil it
request.GET['pwd'] = 'iloveyou'

Mettre à jour

La manière Django sanctionnée est: request.GET.copy ().

Selon le docs :

Les QueryDicts sur request.POST et request.GET seront immuables lorsqu’ils sont accédés dans un cycle normal de requête/réponse. Pour obtenir une version mutable, vous devez utiliser QueryDict.copy ().

Rien ne garantit le futur Django utiliseront _ mutable. Cela a plus de chances de changer que la méthode copy ().

42
laffuste

Vous ne devez pas utiliser GET pour envoyer le nom d'utilisateur et le mot de passe, ce qui est une mauvaise pratique (car il affiche les informations dans la barre d'URL et peut poser un risque de sécurité ). Au lieu de cela, utilisez POST. De plus, je suppose que vous essayez d'authentifier vos utilisateurs et il semble que vous faites trop de travail (création d'un nouveau middleware) pour traiter quelque chose de complètement intégré, pour prendre l'exemple de la documentation :

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.

Moi-même, j'aime bien utiliser le décorateur login_required , très simple à utiliser. J'espère que ça t'as aidé

5
yuvi