Get DataError: value too long for type character varying for every string
Get DataError: value too long for type character varying for every string
我的项目使用 Django+Postgres。我尝试实现用户注册,但是当我尝试发送包含用户名和密码的表单时,出现数据库错误
psycopg2.errors.StringDataRightTruncation: value too long for type character varying(32)
该错误出现在每个字符串作为密码时,即使其长度小于 32。我尝试打印表单值,所以它们与我输入的相同。值太长错误的原因是什么?
models.py
class Person(AbstractUser):
username = models.fields.CharField(max_length=50,unique=True)
password = models.fields.CharField(max_length=32)
forms.py
class RegisterForm(ModelForm):
username = forms.CharField(max_length=100)
password = forms.CharField(widget=PasswordInput())
class Meta:
model = Person
fields = ["username", "password"]
views.py
def register(request):
context={}
if request.method == 'POST':
form = RegisterForm(data=request.POST)
if form.is_valid():
username = request.POST['username']
password = request.POST['password']
print('username: '+username)
print('password: '+password)
if len(Person.objects.filter(username=username))==0:
Person.objects.create_user(username=username, password=password)
else:
context['form_errors']=['Person with this username already exists']
else:
form = RegisterForm()
错误
Django 默认情况下,散列 密码作为安全措施,因此散列密码长于 32 个字符。事实上,在 How Django stores passwords section of the documentation 中,它表明它将密码存储为:
<algorithm>$<iterations>$<salt>$<hash>
一个例子可以是:
pbkdf2_sha256000$Pjun1TMGEQnM$lShdzU33covbDNiqGVDffdHh/86VaECJlaaNXchT0ew=
不可能重建原始密码(假定散列器是 safe 散列器),只能检查密码是否匹配。如果有人设法访问数据库,该人仍然无法读取真实密码。由于人们通常倾向于在多个站点上使用相同的密码,这将是一个严重 安全风险。
因此您需要更多 space 来存储 散列 密码。 Django 的标准用户模型使用 128 个字符。所以你将其实现为:
class Person(AbstractUser):
username = models.fields.CharField(max_length=50, unique=True)
password = models.fields.CharField(max_length=128)
您可以让表单检查 username
是否是唯一的,因此可以使用:
class RegisterForm(ModelForm):
class Meta:
model = Person
fields = ['username', 'password']
widgets = {
'password': PasswordInput()
}
def save(self, *args, commit=True, **kwargs):
person = super().save(*args, commit=commit, **kwargs)
person.<strong>set_password(</strong>self.cleaned_data['password']<strong>)</strong>
if commit:
person.save()
return person
通过不手动指定表单字段,Django 还将验证用户名的最大长度(50 个字符),并检查其唯一性。
然后您可以用作视图:
def register(request):
if request.method == 'POST':
form = RegisterForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('<em>name-of-some-view</em>')
else:
form = RegisterForm()
context = {'form': form}
# …
我的项目使用 Django+Postgres。我尝试实现用户注册,但是当我尝试发送包含用户名和密码的表单时,出现数据库错误
psycopg2.errors.StringDataRightTruncation: value too long for type character varying(32)
该错误出现在每个字符串作为密码时,即使其长度小于 32。我尝试打印表单值,所以它们与我输入的相同。值太长错误的原因是什么?
models.py
class Person(AbstractUser):
username = models.fields.CharField(max_length=50,unique=True)
password = models.fields.CharField(max_length=32)
forms.py
class RegisterForm(ModelForm):
username = forms.CharField(max_length=100)
password = forms.CharField(widget=PasswordInput())
class Meta:
model = Person
fields = ["username", "password"]
views.py
def register(request):
context={}
if request.method == 'POST':
form = RegisterForm(data=request.POST)
if form.is_valid():
username = request.POST['username']
password = request.POST['password']
print('username: '+username)
print('password: '+password)
if len(Person.objects.filter(username=username))==0:
Person.objects.create_user(username=username, password=password)
else:
context['form_errors']=['Person with this username already exists']
else:
form = RegisterForm()
错误
Django 默认情况下,散列 密码作为安全措施,因此散列密码长于 32 个字符。事实上,在 How Django stores passwords section of the documentation 中,它表明它将密码存储为:
<algorithm>$<iterations>$<salt>$<hash>
一个例子可以是:
pbkdf2_sha256000$Pjun1TMGEQnM$lShdzU33covbDNiqGVDffdHh/86VaECJlaaNXchT0ew=
不可能重建原始密码(假定散列器是 safe 散列器),只能检查密码是否匹配。如果有人设法访问数据库,该人仍然无法读取真实密码。由于人们通常倾向于在多个站点上使用相同的密码,这将是一个严重 安全风险。
因此您需要更多 space 来存储 散列 密码。 Django 的标准用户模型使用 128 个字符。所以你将其实现为:
class Person(AbstractUser):
username = models.fields.CharField(max_length=50, unique=True)
password = models.fields.CharField(max_length=128)
您可以让表单检查 username
是否是唯一的,因此可以使用:
class RegisterForm(ModelForm):
class Meta:
model = Person
fields = ['username', 'password']
widgets = {
'password': PasswordInput()
}
def save(self, *args, commit=True, **kwargs):
person = super().save(*args, commit=commit, **kwargs)
person.<strong>set_password(</strong>self.cleaned_data['password']<strong>)</strong>
if commit:
person.save()
return person
通过不手动指定表单字段,Django 还将验证用户名的最大长度(50 个字符),并检查其唯一性。
然后您可以用作视图:
def register(request):
if request.method == 'POST':
form = RegisterForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('<em>name-of-some-view</em>')
else:
form = RegisterForm()
context = {'form': form}
# …