Я сделал форму «редактировать профиль», где вы можете сделать очень классическую вещь: сменить пароль.

Таким образом, у меня есть 3 поля: старый пароль, новый пароль и новый пароль еще раз.

Проблема в дизайне. Сначала я проверяю, все ли набрано в порядке в форме clean method :

def clean(self):
    old = self.cleaned_data.get('old_password')
    new1 = self.cleaned_data.get('new_password1')
    new2 = self.cleaned_data.get('new_password2')
    if old:
        if not new1:
            raise ValidationError(_(u'New password missing'))
        if not new2:
            raise ValidationError(_(u'New password missing'))
        if new1 != new2:
            raise ValidationError(_(u"The new password "
                                    u"is not the same twice"))
    return super(ProfileForm, self).clean()

Из моей формы, если я не взломаю, я не могу получить доступ к пользователю, который в настоящее время вошел в систему. У меня вопрос о дизайне: лучше ли взломать код формы и поменять там пароль на форму is_valid() , или лучше сделать это с помощью метода view form_valid() ?

0
Olivier Pons 5 Янв 2016 в 20:31

2 ответа

Лучший ответ

Django фактически имеет встроенную форму для изменения пароля пользователя, на которую вы можете ссылаться. См. SetPasswordForm и PasswordChangeForm на странице https://github.com/django/django/blob/master/django/contrib/auth/forms.py.

Не меняйте пароль в методе is_valid(), он используется только для проверки. Вы можете переопределить форму __init__, чтобы принять пользователя, и метод save, чтобы изменить пароль.

class MyForm(forms.Form):

    def __init__(self, user, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.user =  user

    def save(self, commit=True):
        password = self.cleaned_data["new_password1"]
        self.user.set_password(password)
        if commit:
            self.user.save()
        return self.user

Операцию по смене пароля нужно делать в форме отдельным методом. Вот пример кода просмотра, который вам понадобится:

class MyView(TemplateView):

    def post(self, request, *args, **kwargs):
        form = MyForm(user=request.user, data=request.POST)
        if form.is_valid():
            form.save() # password updated
            return redirect(<somehwere>)

        # the password change has failed form validation
        return self.render_to_response({})

Чтобы ответить на ваш вопрос, лучше изменить пароль в формах, а не в представлении. Это довольно распространенный шаблон в Django для выполнения операций с данными в формах (например, ModelForm.save ()), и большая часть собственного кода Django также изменяет данные модели в формах.

Это отделяет логику изменения данных модели от представления и значительно упрощает модульное тестирование и рассуждение (например, вам не нужно полагаться на представление для проверки операции смены пароля).

2
Derek Kwok 5 Янв 2016 в 18:05

Во-первых, Django поставляется с представлением < / a> и form для смены паролей], по возможности используйте их.

Если вам действительно нужно исправить собственное представление и форму, я думаю, что можно изменить пароль в методе views form_valid().

Вы можете переместить код, устанавливающий новый пароль, в метод в форме, а затем вызвать этот метод в методе form_valid. Недостатком этого подхода является то, что вам придется переопределить метод формы __init__ и метод представления get_form_kwargs, чтобы передать пользователя в форму, что усложняет ее. Преимущество состоит в том, что вы инкапсулировали функциональность в представлении.

Не отменяйте метод формы is_valid(). Цель этого метода - проверить, действительна ли форма. Вам редко нужно его отменять.

0
Alasdair 5 Янв 2016 в 17:55