社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

为什么在Django检查两个密码是否匹配如此复杂?

Mark • 6 年前 • 2029 次点击  

是我做错了什么,还是这个? 认真地 每当我想检查两个字段是否相同时,开发人员希望我编写什么?

def clean(self):
    data = self.cleaned_data
    if "password1" in data and "password2" in data:
        if data["password1"] != data["password2"]:
            self._errors["password2"] = self.error_class(['Passwords do not match.'])
            del data['password2']    
    return data

为什么我必须验证用户名是唯一的?

def clean_username(self):
    data = self.cleaned_data['username']
    if User.objects.filter(username=data).exists():
        raise ValidationError('Username already taken.')
    return data

这是一个 ModelForm . 它应该已经知道有一个独特的约束?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/30344
 
2029 次点击  
文章 [ 4 ]  |  最新文章 6 年前
Amarghosh
Reply   •   1 楼
Amarghosh    15 年前

您可能需要添加 else: 第一部分 if . 当前函数返回 data 即使其中一个密码不存在,也不会设置任何错误-这是预期的行为吗?

else:
    self._errors["password"] = self.error_class(['One or both of the passwords not found'])

if "password1" in data and "password2" in data: 这确保两个密码都存在。如果没有这一行,您将在下一行中看到一个错误 data[password1] data[password2] 如果他们中的任何一个不在场。

接下来的三行比较密码并设置适当的错误消息——这是必需的,不是吗?

正如他们所说,使事情尽可能简单,不再是。

StefanNch
Reply   •   2 楼
StefanNch    14 年前

http://k0001.wordpress.com/2007/11/15/dual-password-field-with-django/


编辑:找到管理表单处理问题的方式: http://code.djangoproject.com/svn/django/trunk/django/contrib/auth/forms.py

class AdminPasswordChangeForm(forms.Form):
    """
    A form used to change the password of a user in the admin interface.
    """
    password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
    password2 = forms.CharField(label=_("Password (again)"), widget=forms.PasswordInput)

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

    def clean_password2(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')
        if password1 and password2:
            if password1 != password2:
                raise forms.ValidationError(_("The two password fields didn't match."))
        return password2

    def save(self, commit=True):
        """
        Saves the new password.
        """
        self.user.set_password(self.cleaned_data["password1"])
        if commit:
            self.user.save()
        return self.user
Daniel Roseman
Reply   •   3 楼
Daniel Roseman    15 年前

首先,你是 认真地 抱怨四行炉号?如果它真的困扰你,创建一个 PasswordForm 类,它包含干净的逻辑,并根据需要为您自己的窗体子类。

其次,你 不要 必须手动验证唯一约束。正如您所说,ModelForm为您完成了这项工作。

评论后编辑

这种“奇怪的语法”是因为检查两个密码字段是否匹配是 不同流量 比正常情况下的情况要好。首先,你要检查主系统 clean 方法而不是字段特定的 clean_myfield . 如果是后者,只需引发一个异常,Django确实会删除字段数据。

所以不,这不是每个表单上的7行-参见我关于子类化的注释-而且它 当然 不是7行乘以多个字段,因为您不想对任何其他类型的字段执行此操作。

Yuji 'Tomita' Tomita
Reply   •   4 楼
Yuji 'Tomita' Tomita    14 年前

我要做的是:

这是唯一需要定义的干净方法,以确保2个密码正确并且用户名有效。

使用 clean_fieldname 方法,这样您就不需要做更多的工作来验证用户名。

def clean_password2(self):
    password1 = self.cleaned_data.get('password1')
    password2 = self.cleaned_data.get('password2')

    if not password2:
        raise forms.ValidationError("You must confirm your password")
    if password1 != password2:
        raise forms.ValidationError("Your passwords do not match")
    return password2

你说得对,你 需要验证用户名是否唯一,因为ModelForm知道用户名必须唯一。

您的代码的问题是您正在重写 clean() 方法,这意味着ModelForm没有执行其“real”clean()。

要获取默认验证,请调用 super(MyForm, self).clean() 或者最好还是不要重写 clean 一点也不例外 clean_password2 .