6

omab/django-social-authを使用している自分のWebサイトにFacebook認証があります

ユーザーを別のWebサイトにリダイレクトして、詳細を入力してもらいたい。そのため、ユーザーが最初にFacebookアカウントで認証し、フォームに入力した後、ユーザーをアクティブユーザーとして保存するときに非アクティブとしてユーザーを設定したいと思います。

is_activeフィールドをdefault=Falseとして使用する場合と同様に、自分の環境でdjango / contrib / auth/models.pyを操作しました。ただし、アクティブユーザーとして保存されますが、管理パネルから通常のユーザーを追加しても同じ結果になります。足りないものはありますか?

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
4

3 に答える 3

15
  1. ビルトインの変更は避けてください。物事を行うためのより良い方法があります。
  2. 信号のように。信号は素晴らしいです。
  3. この場合、のpre_saveシグナルにアタッチし、モデルインスタンスdjango.contrib.auth.models.Userのプロパティを手動で修正しis_activeます(オブジェクトが新しい場合)。
  4. このように、ロジックを追加して、ユーザーを非アクティブとして適切にマークしていることを確認できます。
  5. 管理者がそれらをアクティブとしてマークした場合、管理者内に追加されたユーザーはおそらくアクティブであるはずです。
于 2013-02-27T21:38:57.653 に答える
10

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を介してそれらをアクティブ化する方法がなくなります。

于 2017-01-26T18:17:08.543 に答える
7

django-allauthを使用する場合のエレガントなソリューション。

別の非常に素晴らしい解決策があります..あなたが望むものと非常によく似ているものです。

設定を介してdjango-allauthに渡すことができるカスタムフォーム(私の場合はModelForm)を作成しました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()
于 2014-09-11T22:06:49.533 に答える