1
votes

Comment utiliser la validation de mot de passe Django dans mes vues existantes?

J'ai un django views.py existant sur lequel j'ai appliqué une logique de validation de mot de passe, de nom d'utilisateur et d'e-mail. Cependant, à l'avenir, je dois appliquer une validation de mot de passe plus avancée. pour par exemple limitation de longueur de mot de passe, sensibilité en majuscules, etc. J'ai un code écrit pour une validation avancée, mais je ne suis pas en mesure de les appliquer sur mes vues.py existantes. Vous trouverez ci-dessous le code de views.py

ValidationError at /accounts/register/
['The password must contain at least 1 uppercase letter, A-Z.']
Request Method: POST
Request URL:    http://127.0.0.1:8000/accounts/register/
Django Version: 2.1.5
Exception Type: ValidationError
Exception Value:    
['The password must contain at least 1 uppercase letter, A-Z.']
Exception Location: /root/PycharmProjects/interview/ACCOUNTS/validator.py in validate, line 45
Python Executable:  /root/PycharmProjects/myvenv/bin/python
Python Version: 3.6.7
Python Path:    
['/root/PycharmProjects/interview',
 '/usr/lib/python36.zip',
 '/usr/lib/python3.6',
 '/usr/lib/python3.6/lib-dynload',
 '/root/PycharmProjects/myvenv/lib/python3.6/site-packages']
Server time:    Wed, 6 Feb 2019 07:15:39 +0000

Voici le code de validation avancée du mot de passe de validate.py

I imported the validator.py in the views.py,and tried to call the module.function inside the password field as below

password = request.POST['password', validator.MinimumLengthValidator]

J'ai essayé ci-dessous étapes.

import re    
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _    

class MinimumLengthValidator:
    def __init__(self, min_length=8):
        self.min_length = min_length

    def validate(self, password, user=None):
        if len(password) < self.min_length:
            raise ValidationError(
                _("This password must contain at least %(min_length)d characters."),
                code='password_too_short',
                params={'min_length': self.min_length},
            )

    def get_help_text(self):
        return _(
            "Your password must contain at least %(self.min_length)d characters."
            % {'min_length': self.min_length}
        )


class NumberValidator(object):
    def validate(self, password, user=None):
        if not re.findall('\d', password):
            raise ValidationError(
                _("The password must contain at least %(min_digits)d digit(s), 0-9."),
                code='password_no_number',
            )

    def get_help_text(self):
        return _(
            "Your password must contain at least 1 digit, 0-9."
        )


class UppercaseValidator(object):
    def validate(self, password, user=None):
        if not re.findall('[A-Z]', password):
            raise ValidationError(
                _("The password must contain at least 1 uppercase letter, A-Z."),
                code='password_no_upper',
            )

    def get_help_text(self):
        return _(
            "Your password must contain at least 1 uppercase letter, A-Z."
        )

Mais cela ne fonctionne pas. Si j'ai raison, je peux écrire une classe mixin et l'appeler dans mon views.py. Mais j'utilise des vues basées sur les fonctions. Donc, je ne suis pas sûr de pouvoir utiliser mixin. Veuillez suggérer comment pouvons-nous obtenir le résultat souhaité.

Nouvelle erreur:

from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib import messages
from . import validator
def register(request):
    if request.method == 'POST':
        first_name = request.POST['first_name']
        last_name = request.POST['last_name']
        email = request.POST['email']
        username = request.POST['username']
        password = request.POST['password', validator.MinimumLengthValidator]
        password2 = request.POST['password2']

        # check if the password match
        if password == password2:

            if User.objects.filter(username=username).exists():
                messages.error(request, 'username already exist')
                return redirect('register')
            else:
                if User.objects.filter(email=email).exists():
                    messages.error(request, 'Registration Failed - Try different email address')
                    return redirect('register')
                else:
                    user = User.objects.create_user(username=username, password=password, email=email,
                                                    first_name=first_name, last_name=last_name)
                    user.save()
                    messages.success(request, 'Registration complete, please proceed to login')
                    return redirect('register')
        else:
            messages.error(request, 'password dose not match')
            return redirect('register')
    else:
        return render(request, 'ACCOUNTS/register.html')


0 commentaires

3 Réponses :


1
votes

Vous devez utiliser des formulaires pour utiliser proprement ces validateurs . Bien que vous deviez également les modifier.

def register(request):
    validators = [MinimumLengthValidator, NumberValidator, UppercaseValidator]
    if request.method == 'POST':
       # some code
       password = request.POST('password')
       try:
           for validator in validators:
                validator().validate(password)
       except ValidationError as e:
           messages.error(request, str(e))
           return redirect('register')

Ensuite, mettez à jour le form :

# in forms

class UserForm(forms.Form): 
  password = forms.CharField(widget=forms.PasswordInput(),validators=[min_length])

Mais, si vous ne voulez pas utiliser les formulaires django, vous devez exécuter ces validations manuellement, par exemple:

def min_length(password):  # validator
    if not re.findall('\d', password):
        raise ValidationError(
            _("The password must contain at least %(min_digits)d digit(s), 0-9."),
            code='password_no_number',
        )


6 commentaires

J'ai créé un objet du module de validation et appelé toutes les fonctions dans celui-ci comme indiqué par vous. Mais j'obtiens une erreur dans mon IDE "référence non résolue pour tous.


Vous devez les importer à partir du fichier que vous avez écrit, en utilisant de votre_validator_file import MinimumLengthValidator, NumberValidator, UppercaseValidator


Pouvez-vous essayer comme ceci: validators = [validator.MinimumLengthValidator, validator.NumberValidator, validator.UppercaseValidator] ?


Merci pour votre aide et votre suggestion fonctionne. Mais une dernière chose. Lorsque j'entre un mot de passe qui ne correspond pas aux critères, j'obtiens les erreurs souhaitées. Mais je ne reçois pas ces erreurs sur l'interface utilisateur, j'obtiens une façon django de lancer des erreurs. J'ai publié l'erreur dans le message d'origine.


@learner Je pense que vous pouvez examiner ceci: docs.djangoproject.com/en /2.1/ref/contrib/messages


Merci beaucoup pour votre aide, la solution fonctionne comme vous le souhaitez. Cheerz



0
votes

Vous pouvez créer une classe de formulaire personnalisée et l'utiliser pour valider le corps de votre requête.

form = YourCustomValidationForm(request.POST)
if form.is_valid():
   pass
else:
   #fail

Dans views.py Créez une instance de cette classe avec les valeurs du corps de la requête.

from django.forms import ModelForm
from yourApp.models import YourModel

# Create the form class.
class YourCustomValidationForm(ModelForm):
     class Meta:
         model = YourModel
         fields = ['field1', 'field2']
     def clean_psswd(self):
          #custom validation


0 commentaires

0
votes

vous pouvez utiliser votre propre validation, sans utiliser la validation intégrée de django, comme suit:

password = "mypassword_Q@1"

if len(password) < 8 or password.lower() == password or password.upper() == password or password.isalnum()\
        or not any(i.isdigit() for i in password):
    print('your password is weak ')

else:
    print('your password is strong ')


0 commentaires