gpt4 book ai didi

django - Django 表单中的奇怪行为

转载 作者:行者123 更新时间:2023-12-03 23:48:56 26 4
gpt4 key购买 nike

我正在使用 Django Forms ,我正在对一个字段进行自定义验证,但遇到了奇怪的问题。

forms.py

class RegistrationForm(forms.Form):
username = forms.CharField(max_length=50)
email = forms.EmailField(required=False)
password = forms.CharField(max_length=50)
password1 = forms.CharField(max_length=50)

def clean_password(self):
password = self.cleaned_data['password']
print(self.cleaned_data) # all fields are present except password1 in cleaned Data
re_password = self.cleaned_data['password1'] #Gives Key Error here
# Do something

在这里,当我尝试对 clean_password 中的密码字段进行一些验证时函数,它给出了 password1 的关键错误领域,我不明白为什么会这样。我尝试了很多搜索,但找不到任何相关的内容,关于导致此错误的原因。但是后来我尝试对代码进行一些更改,并且它起作用了,但我不知道它为什么起作用。

modified_forms.py
class RegistrationForm(forms.Form):
username = forms.CharField(max_length=50)
email = forms.EmailField(required=False)
password1 = forms.CharField(max_length=50) #swapped position
password = forms.CharField(max_length=50)

def clean_password(self):
password = self.cleaned_data['password']
print(self.cleaned_data) # all fields are present in cleaned Data
re_password = self.cleaned_data['password1'] #Doesn't Give Key Error here
# Do something

我所做的改变只是 交换 password1的线路位置和 password ,也就是说我只是改变了 password的顺序和 password1 .我换了订单 password1password 行, password在位置是 password1 .它解决了错误我不理解这种行为,因为我知道字段顺序不应该影响任何事情。有人可以解释一下这里发生了什么吗?谢谢 :)

最佳答案

这不是奇怪的行为。 Django 表单以这种方式工作。请看源码here了解 Django 表单的字段清理如何工作。这是 _clean_fields 的精简版方法。

def _clean_fields(self):
for name, field in self.fields.items():
# skipped
try:
# skipped
value = field.clean(value)
self.cleaned_data[name] = value
if hasattr(self, 'clean_%s' % name):
# skipped
value = getattr(self, 'clean_%s' % name)()
self.cleaned_data[name] = value
except ValidationError as e:
self.add_error(name, e)

它所做的是循环表单字段,并且对于每个字段,将其清理后的值放入 cleaned_data字典。如果定义了清理字段的方法( clean_<FIELD_NAME> ),它会对该字段的清理数据调用该方法并将其放入 cleaned_data字典。

在您的第一种情况下 password1紧随其后 password .因为字段是按顺序清理的, password1当您尝试在 clean_password 中访问它时尚未清除方法。这意味着它的清洁值在 cleaned_data 中尚不存在。字典。

在第二种情况下,您交换 password 的位置和 password1 .现已对 password1进行了清洗并且您可以访问它的值。

经验法则是 clean_<FIELD_NAME>方法,您只能访问在该特定字段之前声明的那些字段的清理值 .

解决方案

你应该像 django 在它的 UserCreationForm 中那样做.他们检查第二个字段的密码匹配,即 password1 应该匹配密码,反之亦然(本质上是相同的)。修改自 here 的片段.
def clean_password1(self):
password = self.cleaned_data.get("password")
password1 = self.cleaned_data.get("password1")
if password and password1 and password != password1:
raise forms.ValidationError('Passwords do not match')
return password1

关于django - Django 表单中的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60537504/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com