Добавление кода приглашения для регистрации в django

#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 в свою форму