Saving custom user model with django-allauth

后端 未结 3 2119
长情又很酷
长情又很酷 2021-01-02 17:54

I have django custom user model MyUser with one extra field:

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

class MyUser(Abstr         


        
3条回答
  •  醉话见心
    2021-01-02 18:26

    Though it is a bit late but in case it helps someone.

    You need to create your own Custom AccountAdapter by subclassing DefaultAccountAdapter and setting the

    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()
    

    and you also need to define the following in settings:

    ACCOUNT_ADAPTER = 'api.adapter.UserAccountAdapter'
    

    This is also useful, if you have a custom SignupForm to create other models during user registration and you need to make an atomic transaction that would prevent any data from saving to the database unless all of them succeed.

    The DefaultAdapter for django-allauth saves the user, so if you have an error in the save method of your custom SignupForm the user would still be persisted to the database.

    So for anyone facing this issue, your CustomAdpater would look like this

    class 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
    

    Then you can decorate your custom SignupForm's with @transaction.atomic

    @transaction.atomic
    def save(self, request, user):
        user.save() #save the user object first so you can use it for relationships
        ...
    

提交回复
热议问题