7

追加のフィールドが 1つある djangoカスタム ユーザー モデルがあります。 MyUser

# models.py
from django.contrib.auth.models import AbstractUser

class MyUser(AbstractUser):
    age = models.PositiveIntegerField(_("age"))

# settings.py
AUTH_USER_MODEL = "web.MyUser"

これらの指示に従って、カスタムの全認証サインアップ フォーム クラスも用意しています。

# forms.py
class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30)
    last_name = forms.CharField(max_length=30)
    age = forms.IntegerField(max_value=100)

    class Meta:
        model = MyUser

    def save(self, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.age = self.cleaned_data['age']
        user.save()

# settings.py
ACCOUNT_SIGNUP_FORM_CLASS = 'web.forms.SignupForm'

送信後SignupForm(プロパティのフィールドMyUser.ageが正しくレンダリングされます)、次のエラーが発生します。

/accounts/signup/ の IntegrityError
(1048、「列 'age' を null にすることはできません」)

カスタム ユーザー モデルを保存する適切な方法は何ですか?

ジャンゴ-allauth: 0.12.0; ジャンゴ: 1.5.1; パイソン 2.7.2

4

3 に答える 3

13

少し遅れていますが、誰かを助ける場合に備えて。

DefaultAccountAdapter をサブクラス化し、

class UserAccountAdapter(DefaultAccountAdapter):

    def save_user(self, request, user, form, commit=True):
        """
        This is called when saving user via allauth registration.
        We override this to set additional data on user object.
        """
        # Do not persist the user yet so we pass commit=False
        # (last argument)
        user = super(UserAccountAdapter, self).save_user(request, user, form, commit=False)
        user.age = form.cleaned_data.get('age')
        user.save()

また、設定で以下を定義する必要があります。

ACCOUNT_ADAPTER = 'api.adapter.UserAccountAdapter'

これは、ユーザー登録中に他のモデルを作成するためのカスタム SignupForm があり、すべてが成功しない限りデータがデータベースに保存されないようにするアトミック トランザクションを作成する必要がある場合にも役立ちます。

DefaultAdapterfor django-allauth はユーザーを保存するため、カスタム SignupForm のメソッドにエラーがある場合でもsave、ユーザーはデータベースに永続化されます。

したがって、この問題に直面している人にとっては、次のCustomAdpaterようになります

クラス UserAccountAdapter(DefaultAccountAdapter):

    def save_user(self, request, user, form, commit=False):
        """
        This is called when saving user via allauth registration.
        We override this to set additional data on user object.
        """
        # Do not persist the user yet so we pass commit=False
        # (last argument)
        user = super(UserAccountAdapter, self).save_user(request, user, form, commit=commit)
        user.age = form.cleaned_data.get('age')
        # user.save() This would be called later in your custom SignupForm

次に、カスタム SignupForm を次のように装飾できます。@transaction.atomic

@transaction.atomic
def save(self, request, user):
    user.save() #save the user object first so you can use it for relationships
    ...
于 2016-08-27T10:36:46.427 に答える
0

SignupForm のクラス Meta でフィールド プロパティを定義し、次のように年齢を含むフィールドのリストを設定する必要があると思います。

class SignupForm(forms.Form):
...
   class Meta:
      model = MyUser
      fields = ['first_name', 'last_name', 'age']

うまくいかない場合は、 これを見てください

于 2015-10-13T09:26:01.150 に答える