我正在将django-rest-auth与自定义用户模型,注册视图和序列化程序一起使用。我想要实现的是电子邮件登录而不是用户名。 api视图可以正确显示,但是在发布时出现错误:
TypeError at /rest-auth/registration/
save() takes 1 positional argument but 2 were given
这是回溯:http://dpaste.com/2FR3DZY
serializer.py
class CustomUserSerializer(serializers.ModelSerializer):
"""Serializer for User objects."""
class Meta:
model = models.User
fields = ('id', 'email', 'name', 'password')
extra_kwargs ={'password': {'write_only': True}}
def create(self, validated_data):
"""Create and return a new User."""
user = models.User(
email=validated_data['email'],
name=validated_data['name']
)
user.set_password(validated_data['password'])
user.save()
return user
views.py
class CustomRegistrationsView(RegisterView):
serializer_class = CustomUserSerializer
urls.py
path('rest-auth/registration/', CustomRegistrationsView.as_view(), name='rest_register'),
path('rest-auth/', include('rest_auth.urls')),
models.py
class UserManager(BaseUserManager):
"""Helps Django work with our custom user model."""
def create_user(self, email, name, password=None):
"""Creates a new user object."""
if not email:
raise ValueError('Users must have an email address.')
email = self.normalize_email(email)
user = self.model(email=email, name=name)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, name, password):
"""Creates and saves a new superuser with given details."""
user = self.create_user(email, name, password)
user.is_superuser = True
user.is_staff = True
user.save(using=self._db)
return user
class User(AbstractBaseUser, PermissionsMixin):
"""Represents a "user" inside our system."""
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['name']
def get_full_name(self):
"""Used to get a users full name."""
return self.name
def get_short_name(self):
"""Used to get a users short name."""
return self.name
def __str__(self):
"""Django uses this when it needs to convert the object to a string"""
return self.email
有人可以建议吗?
答案 0 :(得分:0)
问题是这样的:
django-rest-auth实现了自定义RegisterSerializer
,其中save方法接受一个附加的位置参数请求。
def save(self, request):
该序列化器由djang-rest-auth的RegisterView使用。
普通的序列化程序保存方法如下:
def save(self, **kwargs):
您在视图中使用了自定义序列化程序,其父级为django-rest-auth RegisterView
,但您的save方法没有位置请求参数,因此出现了问题。
RegisterView中的逻辑假定正确的序列化程序实现。
尝试将RegisterSerializer用作序列化程序的父级-您只需要研究它是否可扩展,或者您需要添加/实现其他功能。
但这可能有点棘手。
但是看起来,您有自定义模型,自定义序列化程序,自定义视图-我看不到使用django-rest-auth RegisterView的任何理由。只需实现您的注册视图即可。
答案 1 :(得分:0)
由于您的自定义注册视图继承自RegisterView
,perform_create
中定义的RegisterView
方法将使用基于implementation的请求对象调用序列化程序的save方法,并且由于序列化器继承自ModelSerializer
,save方法不使用任何位置参数,因此会出现错误。
CustomUserSerializer
需要定义一个将请求对象作为参数的保存方法。在django-rest-auth configuration
自定义REGISTER_SERIALIZER必须定义一个def save(self,request)方法,该方法返回用户模型实例。
我建议您看看默认REGISTER_SERIALIZER的implementation,它将指导您自定义序列化器的外观。