Django - при попытке очистить поле электронной почты выбрасывается объект '' dict ', не имеющий атрибута' strip '' - PullRequest
0 голосов
/ 01 апреля 2019

В середине моего проекта я понял, что могу создать учетную запись, используя тот же адрес электронной почты. Это определенно создаст некоторые проблемы позже (восстановление аккаунта и т. Д.).

Поэтому мне пришла в голову идея очистить поле электронной почты, протестировав, чтобы найти учетную запись в базе данных, выполнив поиск по электронной почте.

class UserRegistrationForm(forms.ModelForm):
    ...
    email = forms.CharField(label='Email', widget=forms.EmailInput(attrs={'class':'form-control form-control-sm'}))
    ...


class Meta:
    model = User
    fields = {'username', 'first_name', 'last_name', 'email'}


def clean_email(self):
    email = self.cleaned_data.get('email')
    if User.objects.filter(email=email).exists():
        raise forms.ValidationError("Email is already registered")
    return self.cleaned_data

Это должно быть в состоянии решить проблему, но выбрасывает

'dict' object has no attribute 'strip'

Я также установил очищенную электронную почту в функции.

Вот мой метод регистрации:

def register(request):
    if request.user.is_authenticated:
        return redirect('somewhere')
    else:
        if request.method == "POST":
            user_form = UserRegistrationForm(request.POST)
            if user_form.is_valid():
                # begin google reCaptcha validation
                recaptcha_response = request.POST.get('g-recaptcha-response')
                url = 'https://www.google.com/recaptcha/api/siteverify'
                values = {
                    'secret': GOOGLE_RECAPTCHA_SECRET_KEY,
                    'response': recaptcha_response
                }
                data = urllib.parse.urlencode(values).encode()
                req =  urllib.request.Request(url, data=data)
                response = urllib.request.urlopen(req)
                result = json.loads(response.read().decode()) # end of reCaptcha validation

                if result['success']:
                    # create a new user but avoid saving it yet
                    new_user = user_form.save(commit=False)
                    new_user.set_password(user_form.cleaned_data['password'])
new_user.set_email(user_form.cleaned_data['email'])
                    new_user.save()
                    # automatically create a profile of new user
                    Profile.objects.create(
                        user=new_user,
                        ... )
                    messages.success(request, 'Account created successfully')
                    return render(request, 'account/register_done.html', {'new_user':new_user})
                else:
                    messages.error(request, 'Invalid reCAPTCHA. Please try again.')
        else:
            user_form = UserRegistrationForm()
        return render(request, 'account/register.html', {'user_form': user_form})

Вот обратная связь:

Request Method: POST
Request URL: http://127.0.0.1:8000/account/register/

Django Version: 2.1.7
Python Version: 3.7.0


Traceback:

File "C:\Users\\MyVenv\\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\Users\\MyVenv\\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\\MyVenv\\lib\site-packages\django\core\handlers\base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\\\\account\views.py" in register
  60.             if user_form.is_valid():

File "C:\Users\\MyVenv\\lib\site-packages\django\forms\forms.py" in is_valid
  185.         return self.is_bound and not self.errors

File "C:\Users\\MyVenv\\lib\site-packages\django\forms\forms.py" in errors
  180.             self.full_clean()

File "C:\Users\\MyVenv\\lib\site-packages\django\forms\forms.py" in full_clean
  383.         self._post_clean()

File "C:\Users\\MyVenv\\lib\site-packages\django\forms\models.py" in _post_clean
  403.             self.instance.full_clean(exclude=exclude, validate_unique=False)

File "C:\Users\\MyVenv\\lib\site-packages\django\db\models\base.py" in full_clean
  1137.             self.clean()

File "C:\Users\\MyVenv\\lib\site-packages\django\contrib\auth\models.py" in clean
  338.         self.email = self.__class__.objects.normalize_email(self.email)

File "C:\Users\\MyVenv\\lib\site-packages\django\contrib\auth\base_user.py" in normalize_email
  25.             email_name, domain_part = email.strip().rsplit('@', 1)

Exception Type: AttributeError at /account/register/
Exception Value: 'dict' object has no attribute 'strip'

Не могли бы вы объяснить, что происходит и как это исправить?

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

Ваш метод clean_email должен возвращать значение электронной почты, а не весь текст cleaned_data.

def clean_email(self):
    ...
    return email
1 голос
/ 01 апреля 2019

Гораздо более простой способ сделать это - использовать EmailField в вашей пользовательской модели, если вы создали собственную:

    ...
    email = models.EmailField(max_length=100, unique=True) # default User model doesn't have unique=True
    ...

Параметр unique = True проверит, чтобы убедиться, что то же электронное письмо нев базе данных уже нет.

По умолчанию возникает ошибка, но вы все равно можете использовать свою собственную:

def clean_email(self):
    email = self.cleaned_data.get('email')
    if User.objects.filter(email=email).exists():
        raise forms.ValidationError("Email is already registered")
    return self.cleaned_data

Это может позаботиться о том, что объект "dict" имеетнет атрибута "strip" "ошибка сама по себе.

Кроме того, проблема может заключаться в способе настройки электронной почты.Вместо:

new_user.set_email(user_form.cleaned_data['email'])
new_user.save()

Попробуйте:

new_user.email = user_form.cleaned_data['email'])
new_user.save()

Я не совсем уверен, что делает функция set_email.

...