Получить данныеОшибка: значение слишком длинное для типа символ, изменяющегося для каждой строки
Я использую 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 символов. Действительно, в разделе Как Django хранит пароли в документации показано, что он хранит пароль как:
<algorithm>$<iterations>$<salt>$<hash>
Примером может быть, например, следующее:
pbkdf2_sha256$15000$Pjun1TMGEQnM$lShdzU33covbDNiqGVDffdHh/86VaECJlaaNXchT0ew=
Восстановить оригинальный пароль невозможно (учитывая, что хэшер является safe хэшером), можно только проверить, совпадают ли пароли. Если кому-то удастся получить доступ к базе данных, этот человек все равно не сможет прочитать настоящие пароли. Поскольку люди часто используют один и тот же пароль на нескольких сайтах, это было бы серьезным риском для безопасности.
Таким образом, вам потребуется больше места для хранения паролей hashed. Стандартная модель пользователя 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.set_password(self.cleaned_data['password'])
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('name-of-some-view')
else:
form = RegisterForm()
context = {'form': form}
# …