#django #registration
#django #Регистрация
Вопрос:
Пытаюсь добавить код приглашения к регистрации в django. Я знаю, что есть пакет для регистрации под названием invitation, который позаботится об этом, но, похоже, так и должно быть, вот код для регистрации forms.py:
class RegistrationForm(forms.Form):
"""
Form for registering a new user account.
Validates that the requested username is not already in use, and
requires the password to be entered twice to catch typos.
Subclasses should feel free to add any additional validation they
need, but should avoid defining a ``save()`` method -- the actual
saving of collected user data is delegated to the active
registration backend.
"""
required_css_class = 'required'
username = forms.RegexField(regex=r'^[w.@ -]
Я получаю столбец integrityerror_id_пользователя, который не уникален. Что я делаю не так? Похоже, проблема как-то связана с базой данных sqlite3, но я не могу быть уверен.
Согласно запросу в комментарии, вот трассировка:
Traceback:
File "C:Python27libsite-packagesdjangocorehandlersbase.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "C:Python27libsite-packagesdjangoviewsgenericbase.py" in view
48. return self.dispatch(request, *args, **kwargs)
File "C:Python27libsite-packagesregistrationviews.py" in dispatch
79. return super(RegistrationView, self).dispatch(request, *args, **kwargs)
File "C:Python27libsite-packagesdjangoviewsgenericbase.py" in dispatch
69. return handler(request, *args, **kwargs)
File "C:Python27libsite-packagesregistrationviews.py" in post
35. return self.form_valid(request, form)
File "C:Python27libsite-packagesregistrationviews.py" in form_valid
82. new_user = self.register(request, **form.cleaned_data)
File "C:Python27libsite-packagesregistrationbackendsdefaultviews.py" in register
80. password, site)
File "C:Python27libsite-packagesdjangodbtransaction.py" in inner
224. return func(*args, **kwargs)
File "C:Python27libsite-packagesregistrationmodels.py" in create_inactive_user
88. registration_profile = self.create_profile(new_user)
File "C:Python27libsite-packagesregistrationmodels.py" in create_profile
112. activation_key=activation_key)
File "C:Python27libsite-packagesdjangodbmodelsmanager.py" in create
137. return self.get_query_set().create(**kwargs)
File "C:Python27libsite-packagesdjangodbmodelsquery.py" in create
377. obj.save(force_insert=True, using=self.db)
File "C:Python27libsite-packagesdjangodbmodelsbase.py" in save
463. self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "C:Python27libsite-packagesdjangodbmodelsbase.py" in save_base
551. result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
File "C:Python27libsite-packagesdjangodbmodelsmanager.py" in _insert
203. return insert_query(self.model, objs, fields, **kwargs)
File "C:Python27libsite-packagesdjangodbmodelsquery.py" in insert_query
1593. return query.get_compiler(using=using).execute_sql(return_id)
File "C:Python27libsite-packagesdjangodbmodelssqlcompiler.py" in execute_sql
912. cursor.execute(sql, params)
File "C:Python27libsite-packagesdjangodbbackendsutil.py" in execute
40. return self.cursor.execute(sql, params)
File "C:Python27libsite-packagesdjangodbbackendssqlite3base.py" in execute
344. return Database.Cursor.execute(self, query, params)
Exception Type: IntegrityError at /accounts/register/
Exception Value: column user_id is not unique
Вот, что я считаю, это соответствующий раздел models.py:
def create_inactive_user(self, username, email, password,
site, send_email=True):
"""
Create a new, inactive ``User``, generate a
``RegistrationProfile`` and email its activation key to the
``User``, returning the new ``User``.
By default, an activation email will be sent to the new
user. To disable this, pass ``send_email=False``.
"""
new_user = User.objects.create_user(username, email, password,)
new_user.is_active = False
new_user.save()
registration_profile = self.create_profile(new_user)
if send_email:
registration_profile.send_activation_email(site)
return new_user
create_inactive_user = transaction.commit_on_success(create_inactive_user)
def create_profile(self, user):
"""
Create a ``RegistrationProfile`` for a given
``User``, and return the ``RegistrationProfile``.
The activation key for the ``RegistrationProfile`` will be a
SHA1 hash, generated from a combination of the ``User``'s
username and a random salt.
"""
salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
username = user.username
if isinstance(username, unicode):
username = username.encode('utf-8')
activation_key = hashlib.sha1(salt username).hexdigest()
return self.create(user=user,
activation_key=activation_key)
Комментарии:
1. Пожалуйста, опубликуйте полную обратную трассировку и, если вы используете пользовательскую модель пользователя, код вашей модели.
2. Добавлена обратная трассировка. Это не пользовательская модель пользователя, я просто хочу, чтобы код приглашения возвращал значение true, а затем запускал остальную часть кода, то есть создавал новый экземпляр пользователя, а затем отправлял электронное письмо с подтверждением.
3. Похоже, что профиль регистрации для этого конкретного идентификатора пользователя уже существует. Вы каким-то образом удалили таблицу пользователей и воссоздали ее заново, не очистив таблицу профиля регистрации?
4. @knbk Вы правы. Больше не получает IntegrityError. Функция проверки кода приглашения не запускалась, но я думаю, что смогу это выяснить. Спасибо!
5. Тогда вы также правы в том, что это проблема с SQLite: SQLite3 по умолчанию не проверяет целостность ограничений внешнего ключа. Это позволило вам удалить таблицу пользователей в первую очередь без надлежащей обработки таблицы профиля регистрации.
Ответ №1:
Обратная трассировка указывает, что профиль регистрации с указанным user_id
именем уже существует. Скорее всего, это связано с тем, что таблица пользователей была удалена (сброс auto_increment
статуса id
столбца), но таблица регистрационного профиля не была очищена. Недавно созданный user_id
конфликтует со старым, удаленным user_id
, что приводит к IntegrityError
тому, что user_id
поле в таблице регистрационного профиля больше не уникально.
Эта проблема обычно встречается только с SQLite3, поскольку ограничения внешнего ключа по умолчанию не проверяются на наличие ошибок целостности. Это позволяет вам удалять user
таблицу или ее записи без удаления профилей регистрации или установки внешнего ключа NULL
.
Ответ №2:
Проверьте правильность написания icode
строки. Вы вставили его с пробелом.
Кроме того, эта логика неверна:
if 'icode' != 'happytimes':
Вы сравниваете 2 строки.
И, я думаю, вы хотите создать inviteCode
clean_icode
и запустить там логику:
def clean_icode(self):
"""
Validate invitation code, ==happytimes
"""
if self.cleaned_data['icode'] != 'happytimes':
raise forms.ValidationError(_("You need a valid invite code to register, try again or contact us!"))
else:
return self.cleaned_data['icode']
Комментарии:
1. это имеет смысл. Тем не менее, до сих пор нет результата. обратная трассировка была добавлена выше.
2. Нужно посмотреть models.py . Вероятно, вам нужно добавить
user_id
в свою форму
,
max_length=30,
label=_("Username"),
error_messages={'invalid': _("This value may contain only letters, numbers and @/./ /-/_ characters.")})
email = forms.EmailField(label=_("E-mail"))
password1 = forms.CharField(widget=forms.PasswordInput,
label=_("Password"))
password2 = forms.CharField(widget=forms.PasswordInput,
label=_("Password (again)"))
i code = forms.CharField(widget=forms.PasswordInput,
label=_("Invitation Code"))
def clean_username(self):
"""
Validate that the username is alphanumeric and is not already
in use.
"""
existing = User.objects.filter(username__iexact=self.cleaned_data['username'])
if existing.exists():
raise forms.ValidationError(_("A user with that username already exists."))
else:
return self.cleaned_data['username']
def clean(self):
"""
Verifiy that the values entered into the two password fields
match. Note that an error here will end up in
``non_field_errors()`` because it doesn't apply to a single
field.
"""
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
if self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError(_("The two password fields didn't match."))
return self.cleaned_data
def inviteCode(self):
"""
Validate invitation code, ==happytimes
"""
if 'icode' != 'happytimes':
raise forms.ValidationError(_("You need a valid invite code to register, try again or contact us!"))
else:
return self.cleaned_data['icode']
Я получаю столбец integrityerror_id_пользователя, который не уникален. Что я делаю не так? Похоже, проблема как-то связана с базой данных sqlite3, но я не могу быть уверен.
Согласно запросу в комментарии, вот трассировка:
Вот, что я считаю, это соответствующий раздел models.py:
Комментарии:
1. Пожалуйста, опубликуйте полную обратную трассировку и, если вы используете пользовательскую модель пользователя, код вашей модели.
2. Добавлена обратная трассировка. Это не пользовательская модель пользователя, я просто хочу, чтобы код приглашения возвращал значение true, а затем запускал остальную часть кода, то есть создавал новый экземпляр пользователя, а затем отправлял электронное письмо с подтверждением.
3. Похоже, что профиль регистрации для этого конкретного идентификатора пользователя уже существует. Вы каким-то образом удалили таблицу пользователей и воссоздали ее заново, не очистив таблицу профиля регистрации?
4. @knbk Вы правы. Больше не получает IntegrityError. Функция проверки кода приглашения не запускалась, но я думаю, что смогу это выяснить. Спасибо!
5. Тогда вы также правы в том, что это проблема с SQLite: SQLite3 по умолчанию не проверяет целостность ограничений внешнего ключа. Это позволило вам удалить таблицу пользователей в первую очередь без надлежащей обработки таблицы профиля регистрации.
Ответ №1:
Обратная трассировка указывает, что профиль регистрации с указанным user_id
именем уже существует. Скорее всего, это связано с тем, что таблица пользователей была удалена (сброс auto_increment
статуса id
столбца), но таблица регистрационного профиля не была очищена. Недавно созданный user_id
конфликтует со старым, удаленным user_id
, что приводит к IntegrityError
тому, что user_id
поле в таблице регистрационного профиля больше не уникально.
Эта проблема обычно встречается только с SQLite3, поскольку ограничения внешнего ключа по умолчанию не проверяются на наличие ошибок целостности. Это позволяет вам удалять user
таблицу или ее записи без удаления профилей регистрации или установки внешнего ключа NULL
.
Ответ №2:
Проверьте правильность написания icode
строки. Вы вставили его с пробелом.
Кроме того, эта логика неверна:
if 'icode' != 'happytimes':
Вы сравниваете 2 строки.
И, я думаю, вы хотите создать inviteCode
clean_icode
и запустить там логику:
Комментарии:
1. это имеет смысл. Тем не менее, до сих пор нет результата. обратная трассировка была добавлена выше.
2. Нужно посмотреть models.py . Вероятно, вам нужно добавить
user_id
в свою форму