django-rest-auth错误-save()接受1个位置参数,但给出了2个

时间:2018-07-26 06:27:43

标签: django django-rest-framework django-rest-auth

我正在将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

有人可以建议吗?

2 个答案:

答案 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)

由于您的自定义注册视图继承自RegisterViewperform_create中定义的RegisterView方法将使用基于implementation的请求对象调用序列化程序的save方法,并且由于序列化器继承自ModelSerializer,save方法不使用任何位置参数,因此会出现错误。

CustomUserSerializer需要定义一个将请求对象作为参数的保存方法。在django-rest-auth configuration

中检查以下免税项目
  

自定义REGISTER_SERIALIZER必须定义一个def save(self,request)方法,该方法返回用户模型实例。

我建议您看看默认REGISTER_SERIALIZER的implementation,它将指导您自定义序列化器的外观。