创建默认用户不活动(is_active默认为False)

tun*_*nak 6 django django-models django-authentication

我在我的网站上有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
Run Code Online (Sandbox Code Playgroud)

Jac*_*edd 11

  1. 避免修改内置插件.有更好的方法来做事.
  2. 信号一样.信号很棒.
  3. 在这种情况下,我将附加到pre_save信号django.contrib.auth.models.User,并手动更正is_active模型实例的属性(如果对象是新的).
  4. 这样,您可以添加一些逻辑,以确保正确标记用户不活动.
  5. 因为管理员中添加的用户可能应该处于活动状态,如果管理员将其标记为活动状态.


sha*_*rey 6

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")
Run Code Online (Sandbox Code Playgroud)

这将捕获在保存发生之前创建用户的操作,然后测试此实例状态是否为"添加".这区分了创建和更新模型实例.

如果你不做这个测试,更新用户也将is_active设置为False,最终无法通过django激活它们.


Era*_*ldo 5

使用django-allauth时的优雅解决方案.

还有另一个非常好的解决方案......听起来非常像你想要的.

我创建了一个自定义表单(在我的例子中是一个ModelForm),我可以通过ACCOUNT_SIGNUP_FORM_CLASS设置将其移交给django-allauth .这样做是要求新的潜在用户在注册过程中提供额外的字段.

这有一些非常好的优点:

  1. 除了默认的东西之外,您还可以非常优雅地添加一些字段.
  2. 它适用于社交和"正常"注册.
  3. 无需修补第三方应用.
  4. 您仍然可以修改和维护管理员中的所有内容.
  5. 在自定义表单中,您可以在将新用户实例保存到数据库之前访问该用户实例.这意味着您甚至可以处理提供的信息,例如为他创建配置文件对象,并将用户设置为非活动状态.这是有效的,因为您可以检查一切是否正常..然后只提交所有这些步骤或拒绝带有验证错误的表单.:)

嗯......听起来不错吧?
但它究竟是如何工作的(即看起来像)?
我很高兴你问... ^ _ ^

对于您的用例,它可能看起来像这样:

settings.py

[...]
ACCOUNT_SIGNUP_FORM_CLASS = "<your_app>.forms.SignupForm"
[...]
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)