使用django-allauth保存自定义用户模型 [英] Saving custom user model with django-allauth

查看:162
本文介绍了使用django-allauth保存自定义用户模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有django custom用户模型 MyUser 与一个额外的字段:

 来自django.contrib.auth.models导入的models.py 
AbstractUser

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

#settings.py
AUTH_USER_MODEL =web.MyUser

我也根据这些说明定制all-auth 注册表单类

 #表单.py 
class SignupForm(forms.Form):
first_name = forms.CharField(max_length = 30)
last_name = forms.CharField(max_length = 30)
age =表单。 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 被渲染为corectly),我收到这个错误:


/ account / signup / 中的IntegrityError

(1048,列'年龄不能为空)


存储自定义用户模型的正确方法是什么?



django-allauth:0.12.0; django:1.5.1; Python 2.7.2

解决方案

虽然有点晚了,它有助于某人。



您需要通过子类化DefaultAccountAdapter创建自己的CustomAdapter,并设置

 $ code class UserAccountAdapter(DefaultAccountAdapter)

def save_user(self,request,user,form,commit = True):

这是通过allauth注册保存用户时调用
我们重写此值以设置用户对象的其他数据

#不要保留用户,所以我们通过commit = False
#(最后一个参数)
user = super(UserAccountAdapter,self).save_user(request,user,form,commit = False)
user.age = form.cleaned_data.get('age')
user.save()

,您还需要在设置中定义以下内容: p>

  ACCOUNT_ADAPTER ='api.adap ter.UserAccountAdapter'

如果您有一个自定义SignupForm在用户中创建其他模型,这也很有用注册,并且您需要进行原子事务,以防止任何数据保存到数据库,除非它们都成功。



django-allauth的 DefaultAdapter 保存用户,因此如果您在保存您的自定义SignupForm方法,用户仍然会持久到数据库。



所以对于面临这个问题的任何人,你的 CustomAdpater 将看起来像这样



class UserAccountAdapter(DefaultAccountAdapter):

  def save_user(self,request,user,form,commit = False):

这是通过allauth注册保存用户时调用的。
我们重写这个来设置用户对象的附加数据

#不要保留用户,所以我们通过commit = False
#(最后一个参数)
user = super(UserAccountAdapter,self).save_user(request,user,form,commit = commit)
user.age = form.cleaned_data.get('age')
#user.save()将在您的自定义SignupForm


然后,您可以使用 @ transaction.atomic


$ b $来装饰您的自定义SignupForm b

  @ transaction.atomic 
def save(self,request,user):
user.save()#先保存用户对象,以便您可以使用它为关系
...


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

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

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

# settings.py
AUTH_USER_MODEL = "web.MyUser"

I also have according to these instructions custom all-auth Signup form class:

# 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'

After submitting SignupForm (field for property MyUser.age is rendered corectly), I get this error:

IntegrityError at /accounts/signup/
(1048, "Column 'age' cannot be null")

What is the proper way to store Custom user model?

django-allauth: 0.12.0; django: 1.5.1; Python 2.7.2

解决方案

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
    ...

这篇关于使用django-allauth保存自定义用户模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆