【问题标题】:create() takes exactly 1 argument (2 given) error in Django Rest Framework在 Django Rest Framework 中,create() 恰好采用 1 个参数(给定 2 个)错误
【发布时间】:2023-03-28 16:55:01
【问题描述】:

我正在为我的 API 使用自定义用户模型。以下是我项目的代码:

models.py

class AccountManager(BaseUserManager):
    def create_user(self, email, password=None, **kwargs):
        if not email:
            raise ValueError('Users must have a valid email address.')

        if not kwargs.get('username'):
            raise ValueError('Users must have a valid username.')

        account = self.model(
            email=self.normalize_email(email), username=kwargs.get('username')
        )

        account.set_password(password)
        account.save()

        return account

    def create_superuser(self, email, password, **kwargs):
        account = self.create_user(email, password, **kwargs)

        account.is_staff = True
        account.is_superuser = True
        account.save()

        return account


class Account(AbstractBaseUser):
    email = models.EmailField(unique=True)
    username = models.CharField(max_length=40, unique=True)

    first_name = models.CharField(max_length=40, blank=True)
    last_name = models.CharField(max_length=40, blank=True)

    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    objects = AccountManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username']

    def __unicode__(self):
        return self.email

    def get_full_name(self):
        return ' '.join([self.first_name, self.last_name])

    def get_short_name(self):
        return self.first_name

    def has_perm(self, perm, obj=None):
        return self.is_superuser

    def has_module_perms(self, app_label):
        return self.is_superuser

我正在使用如下 serializers.py

中所示的序列化程序序列化 Account 模型
class AccountSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=False)
    confirm_password = serializers.CharField(write_only=True, required=False)

    class Meta:
        model = Account
        fields = (
            'id', 'email', 'username', 'created_at', 'updated_at',
            'first_name', 'last_name', 'password', 'confirm_password',
        )
        read_only_fields = ('created_at', 'updated_at',)

    def create(self, validated_data):
        return Account.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.username = validated_data.get('username', instance.username)

        instance.save()

        password = validated_data.get('password', None)
        confirm_password = validated_data.get('confirm_password', None)

        if password and confirm_password and password == confirm_password:
            instance.set_password(password)
            instance.save()

        return instance

当然,我有一个视图集,它通过端点 views.py

处理 API 请求
class AccountViewSet(viewsets.ModelViewSet):
    lookup_field = 'username'
    queryset = Account.objects.all()
    serializer_class = AccountSerializer

    def get_permissions(self):
        if self.request.method in permissions.SAFE_METHODS:
            return (permissions.AllowAny(),)

        if self.request.method == 'POST':
            return (permissions.AllowAny(),)

        return (permissions.IsAuthenticated(), IsAccountOwner(),)

    def create(self):
        serializer = self.serializer_class(data=request.data)

        if serializer.is_valid():
            Account.objects.create_user(**serializer.validated_data)

            return Response(serializer.validated_data, status=status.HTTP_201_CREATED)

        return Response({
            'status': 'Bad request',
            'message': 'Account could not be created with received data.'
        }, status=status.HTTP_400_BAD_REQUEST)

当我尝试通过 API 发布新用户时,我收到此错误:

create() takes exactly 1 argument (2 given) error

我也有这个作为我的回溯:

http://dpaste.com/2ED1XSX

那么我到底做错了什么?我基本上遵循了一个教程来做到这一点。有什么帮助吗?非常感谢。

编辑

我修复了缩进错误,但我仍然得到同样的错误:/

【问题讨论】:

  • 好久没碰rest-framework了,这里只是猜测一下:我觉得你的AccountViewSetcreate方法需要把request作为参数.
  • 不,还是同样的错误。不过还是谢谢。
  • 检查了herehere,看来create确实需要第二个参数

标签: python django django-rest-framework


【解决方案1】:

您的缩进是错误的,create()update() 方法应该在“序列化器”级别定义 - 而不是在 Meta 类级别:

class AccountSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=False)
    confirm_password = serializers.CharField(write_only=True, required=False)

    def create(self, validated_data):
        return Account.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.username = validated_data.get('username', instance.username)

        instance.save()

        password = validated_data.get('password', None)
        confirm_password = validated_data.get('confirm_password', None)

        if password and confirm_password and password == confirm_password:
            instance.set_password(password)
            instance.save()

        return instance

    class Meta:
        model = Account
        fields = (
            'id', 'email', 'username', 'created_at', 'updated_at',
            'first_name', 'last_name', 'password', 'confirm_password',
        )
        read_only_fields = ('created_at', 'updated_at',)

请注意,在上面的代码中,我还将它们移到了 Meta 内部类定义之前 - 这通常有助于避免类似的问题。

【讨论】:

  • 关于将函数定义移到 meta 之前的非常好的建议。
  • 我修复了这个令人尴尬的错误,但我仍然遇到同样的错误。还有其他建议吗?
  • @TahmidKhanNafee hm,你重启开发服务器了吗?
  • 是的,当然,重新启动我的虚拟环境,并清除我所有的 cookie。
猜你喜欢
  • 1970-01-01
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
  • 2017-02-19
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
  • 2013-10-29
相关资源
最近更新 更多