Создать пользователя неактивным по умолчанию (активен по умолчанию False)

У меня есть аутентификация facebook на моем веб-сайте, который я использую omab / django-social-auth

Я хочу перенаправить пользователей на другой веб-сайт, чтобы они заполнили свои данные. Поэтому я хочу, чтобы пользователи были неактивны, когда они сначала аутентифицируются со своими аккаунтами facebook, а затем после заполнения формы я сохраняю их как активных пользователей.

Я манипулировал django/contrib/auth/models.py в моей среде, как и с полями is_active по умолчанию=False; но они сохраняются как активные пользователи но все тот же результат, даже я добавляю обычного пользователя из админ-панели. Я что-то упускаю?

class User(models.Model):
"""
Users within the Django authentication system are represented by this
model.

Username and password are required. Other fields are optional.
"""
username = models.CharField(_('username'), max_length=30, unique=True,
    help_text=_('Required. 30 characters or fewer. Letters, numbers and '
                '@/./+/-/_ characters'))
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('e-mail address'), blank=True)
password = models.CharField(_('password'), max_length=128)
is_staff = models.BooleanField(_('staff status'), default=False,
    help_text=_('Designates whether the user can log into this admin '
                'site.'))
is_active = models.BooleanField(_('active'), default=False,
    help_text=_('Designates whether this user should be treated as '
                'active. Unselect this instead of deleting accounts.'))
is_superuser = models.BooleanField(_('superuser status'), default=False,
    help_text=_('Designates that this user has all permissions without '
                'explicitly assigning them.'))
last_login = models.DateTimeField(_('last login'), default=timezone.now)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
groups = models.ManyToManyField(Group, verbose_name=_('groups'),
    blank=True, help_text=_('The groups this user belongs to. A user will '
                            'get all permissions granted to each of '
                            'his/her group.'))
user_permissions = models.ManyToManyField(Permission,
    verbose_name=_('user permissions'), blank=True,
    help_text='Specific permissions for this user.')
objects = UserManager()


 def create_user(self, username, email=None, password=None):
    """
    Creates and saves a User with the given username, email and password.
    """
    now = timezone.now()
    if not username:
        raise ValueError('The given username must be set')
    email = UserManager.normalize_email(email)
    user = self.model(username=username, email=email,
                      is_staff=False, is_active=False, is_superuser=False,
                      last_login=now, date_joined=now)

    user.set_password(password)
    user.save(using=self._db)
    return user

3 ответов


  1. во избежание изменения встроенных модулей. Есть способы получше.
  2. как сигналы. Сигналы потрясающие.
  3. в этом случае я бы прикрепил к сигналу pre_save django.contrib.auth.models.User, и вручную исправить is_active свойства экземпляра модели (если объект новый).
  4. таким образом, вы можете добавить некоторую логику, чтобы убедиться, что вы правильно маркировки пользователь не активный.
  5. потому что пользователь добавлен в Admin, вероятно, должен быть активны, если администратор помечает их как активные.

элегантное решение при использовании django-allauth.

есть еще одно очень хорошее решение.. это звучит очень похоже на то, что вы желаете.

Я создал пользовательскую форму (в моем случае ModelForm), которую я могу передать django-allauth через ACCOUNT_SIGNUP_FORM_CLASS настройка. Что это делает.. попросите нового потенциального пользователя предоставить дополнительные поля во время регистрации.

это имеет некоторые очень хорошие преимущества:

  1. вы можете добавить некоторые поля очень элегантно в дополнение к материалу по умолчанию.
  2. он работает как для социальной, так и для" нормальной " регистрации.
  3. не требуется исправление сторонних приложений.
  4. вы все еще можете изменять и поддерживать все в Администраторе.
  5. в пользовательской форме вы получаете доступ к новому экземпляру пользователя, прежде чем он будет сохранен в база данных. Это означает, что вы даже можете обработать предоставленную информацию, например, создать объект профиля для него и установить пользователь неактивен ..все за один раз. Это работает, потому что вы можете проверить, все ли в порядке.. и только после этого совершите все эти шаги или отклоните форму с ошибкой проверки. :)

хорошо.. звучит хорошо?
Но как именно это работает (т. е. выглядит)?
Я рад, что вы спросили.. ^_^

для вашего случая это может выглядеть так:

settings.py

[...]
ACCOUNT_SIGNUP_FORM_CLASS = "<your_app>.forms.SignupForm"
[...]

forms.py

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30)
    last_name = forms.CharField(max_length=30)

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.is_active = False
        user.save()

jack_shed предложил сигналы, которые помогли мне найти направление, чтобы взять его. Но там все еще была работа, чтобы выяснить, как именно тестировать и модифицировать после получения сигнала.

вот что сработало для меня.

from django.dispatch import receiver
from django.db.models.signals import pre_save
from django.contrib.auth.models import User

@receiver(pre_save, sender=User)
def set_new_user_inactive(sender, instance, **kwargs):
    if instance._state.adding is True:
        print("Creating Inactive User")
        instance.is_active = False
    else:
        print("Updating User Record")

это поймает действие создания пользователя до сохранения, а затем проверьте, является ли это состояние экземпляра "добавлением" или нет. Это отличает создание и обновление экземпляра модели.

Если вы не делаете этот тест, обновление пользовательских наборов is_active до False также, и в конечном итоге нет способа активировать их через django.