在创建新用户 djangorestframework 之前检查用户是不是存在

Posted

技术标签:

【中文标题】在创建新用户 djangorestframework 之前检查用户是不是存在【英文标题】:Check if user exists before creating new user djangorestframework在创建新用户 djangorestframework 之前检查用户是否存在 【发布时间】:2018-04-16 17:53:03 【问题描述】:

到目前为止我有 ->

序列化器:

class UserSerializer(serializers.ModelSerializer):
    """Serializer to map the model instance into json format."""
    class Meta:
        """Map this serializer to a model and their fields."""
        model = User
        fields = ('id','username', 'mobile', 'password', 
                  'first_name','last_name','middle_name', 
                  'profile_pic','short_bio','friends_privacy',
                  'address_1','address_2','city',
                  'state','country','pin','verification_code',
                  'is_active','is_blocked','is_reported',
                  'date_created','date_modified')
        extra_kwargs = 'password': 'write_only': True
        read_only_fields = (
            'date_created', 'date_modified',
            'is_staff', 'is_superuser', 'is_active', 
            'date_joined',)
    def create(self, validated_data):
        mobile_ = validated_data['mobile']
        password_ = validated_data['password']
        username_ = validated_data['username']
        motp = self.context['request'].GET['motp']
        eotp = self.context['request'].GET['eotp']
        email_ = self.context['request'].GET['email']
        mflag = api.views.checkOTP_(mobile_,motp)
        eflag = api.views.checkOTP_(email_,eotp)
        if (mflag and eflag):
            user = User(
            username=username_,
            email =email_,
            password = make_password(password_),
            mobile = mobile_,
            )
            user.set_password(validated_data['password'])
            user.save()
            return user

查看:

class UserView2(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    model = User

    def get_permissions(self):
        # allow non-authenticated user to create via POST
        return (AllowAny() if self.request.method == 'POST'
                else IsStaffOrTargetUser()),

我需要检查手机和电子邮件的 OTP,以及是否已经存在具有相同手机或电子邮件的用户。 如果用户已经存在,则返回带有错误的 json 响应:already exists!。 如果用户是新用户并且 OTP 错误再次引发错误。 如果用户是新用户且 OTP 正确,请创建一个帐户。

这里的问题是我尝试在def createof UserSerializer 中添加检查otp 验证的功能。但是序列化程序应该返回模型实例。但是如果你看到代码,我只能在 OTP 正确并返回用户实例的情况下创建用户。而且没有else

那么有没有更好的方法来检查视图本身中的 OTP?

【问题讨论】:

【参考方案1】:

我不同意@Anjaneyulu 的观点。 序列化程序也处理对象的创建..因此你有serializer.save()

但是为了为具有相同 OTP 电子邮件/电话的现有用户提出例外,您应该编写自己的 def validate_mobile(self, data)def validate_email(self, data)。 DRF 序列化程序将首先在类中查找这些方法,如果存在则运行它们。因此,您检查这些字段的自定义逻辑可能是:

class UserSerializer(serializers.ModelSerializer):   
    def validate_mobile(self, value):
        ModelClass = self.Meta.model
        if ModelClass.objects.filter(mobile=value).exists():
            raise serializers.ValidationError('already exists')
        return value

    def validate_email_(self, value):
        ModelClass = self.Meta.model
        if ModelClass.objects.filter(email_=value).exists():
            raise serializers.ValidationError('already exists')
        return value
    class Meta:
        model = User
        fields = (
            ...,
        )

【讨论】:

【参考方案2】:

这不是实现它的正确方法。序列化程序仅用于验证目的。您不应该在序列化程序中实现create 方法,而是将其写入ViewSet。创建对象是一种业务逻辑。它应该始终放在ViewSet 中。将验证方法写入序列化程序。我在下面写一个示例代码

序列化器.py

 class UserSerializer(serializers.ModelSerializer):

    def validate_mobile(self, mobile_num):
         is_already_exists = Model.objects.filter(mobile=mobile_num).exists()
         if is_already_exists:
             raise serializers.ValidationError('already exists')
         return mobile_num

    class Meta:
        model = User
        fields = (
           'id','username', 'mobile', 'password',
           'first_name','last_name','middle_name','profile_pic',
           'short_bio','friends_privacy','address_1',
           'address_2','city','state','country',
           'pin','verification_code','is_active',
               'is_blocked','is_reported',
           'date_created','date_modified'
       )
       extra_kwargs = 'password': 'write_only': True
       read_only_fields = (
           'date_created', 'date_modified','is_staff',
           'is_superuser', 'is_active', 'date_joined',
       )

Viewsets.py(业务逻辑)

class UserView2(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get_permissions(self):
        # allow non-authenticated user to create via POST
        return (AllowAny() if self.request.method == 'POST'
                else IsStaffOrTargetUser()),
    def create(self, serializer):
          # your logic goes here.

【讨论】:

如果字段没有更新,更新的情况下不会干扰吗?

以上是关于在创建新用户 djangorestframework 之前检查用户是不是存在的主要内容,如果未能解决你的问题,请参考以下文章

PE下如何创建新用户

ubuntu终端新创建的用户在/home下为啥没有它的文件

如何在 Devise 中手动创建新用户和用户会话?

在创建新用户 djangorestframework 之前检查用户是不是存在

在 xmpp 服务器上创建一个新用户

ubuntu 创建新用户ssh登录