最近在写新版的devops3.0,被generics.CreateAPIView创建用户密码序列化的问题折磨的欲仙欲死。反复看源码测试,得出下面的流程,这也是做generics.CreateAPIView太少的原因。以后一定要更加细心才是!留存本篇博文便于参考!
伪代码:
用户model:
需要导入from django.contrib.auth.models import AbstractUser
AbstractUser继承了AbstractBaseUser, PermissionsMixin两个类之前写第二版kkit的时候就是选择了直接继承AbstractBaseUser, PermissionsMixin。
AbstractUser封装了更多的属性可以供我们调用,如果你们觉得没用,那就还是继承上面那两个就行。
class UserProfile(AbstractUser): img = models.CharField(max_length=10, default='user.jpg') phone = models.CharField(max_length=11, default='None') full_name = models.CharField(max_length=11, default='你好') expire = models.IntegerField(default=100) groups = models.ManyToManyField( Group, verbose_name=_('groups'), blank=True, help_text=_( 'The groups this user belongs to. A user will get all permissions ' 'granted to each of their groups.' ), related_name="user_set", related_query_name="user", ) info = models.CharField(default='', max_length=150) class Meta: permissions = ( ('yo_list_user', u'罗列用户'), ('yo_list_opsuser', u'罗列运维用户'), ('yo_create_user', u'新增用户'), ('yo_update_user', u'修改用户'), ('yo_delete_user', u'删除用户'), ('yo_list_pmngroup', u'罗列权限组'), ('yo_create_pmngroup', u'新增权限组'), ('yo_update_pmngroup', u'修改权限组'), ('yo_delete_pmngroup', u'删除权限组'), ('yo_list_permission', u'罗列所有权限') ) def get_group_name(self): if self.is_superuser == 1: return "超级管理员" # 查看组内有多少条符合的权限 elif self.groups.count() == 0: return "无权限" else: gourp_list = [] groups = self.groups.all() for group in groups: gourp_list.append(group.name) if len(gourp_list) == 0: return '' else: return "-".join(gourp_list) @property def is_expire(self): return not connect.exists(self.username) @is_expire.setter def is_expire(self): connect.set(self.username, self.expire or 1)
创建用户接口:
path(r'v1/user/create/', user.UserCreateAPI.as_view()),
创建用户函数:
因为只是光看创建用户的代码,我删去了自定义的一些验证还有,记录和权限等相关的代码,看看是不是简单的多了。
我们继承generics.CreateAPIView,然后重写create方法,将前端传过来的相关用户数据通过request传递过去。
然后他会找父类的父类 mixins.CreateModelMixin中的create方法进行实例模型的创建。然后我们再写serializers就差不多了。
看到下面的这行了吗?serializer_class = serializers.UserSerializer主要是对前段传递来的数据进行序列化的。嗯!我们再去写这个它。
class UserCreateAPI(generics.CreateAPIView): module = models.UserProfile serializer_class = serializers.UserSerializer queryset = models.UserProfile.objects.all() def create(self, request, *args, **kwargs): response = super(UserCreateAPI, self).create(request, *args, **kwargs) self.get_serializer() return response
序列化函数:
写之前我们先导入之前创建好的模型
from apps.authority.models import UserProfile
然后我们再看写序列化的方法和字段,特别注意我们需要调用set_password方法来保存密码哦!
class UserSerializer(serializers.ModelSerializer): group_name = serializers.StringRelatedField(source="get_group_name", read_only=True) groups = serializers.PrimaryKeyRelatedField(required=False, many=True, queryset=Group.objects.all()) class Meta: model = UserProfile fields = ( 'id', 'is_active', 'phone', 'username', 'full_name', 'group_name', 'groups', 'email', 'info', 'expire', ) read_only_fields = ( 'id', ) # 保存序列化密码并保存 def create(self, validated_data): obj = super(UserSerializer, self).create(validated_data=validated_data) obj.set_password(validated_data.get('password')) obj.save() return obj
好啦!一个创建用户的接口就写完啦。当然在实际中我们需要对其进行权限和账号是否到期等进行相关的限制。因为devops需要时刻采集用户的动作数据,所以呢,我在动作记录上重新写了一张表和相关的数据模板,再写个装饰器进行全局调用。
当然这期我们只聊登录的过程,那就先写这些啦,希望能对看到的各位有所帮助。
PS:采用rest_framework写后端真是好。能省不少力气,但是也需要不断的分析它各种类的源码以方便我们业务调用。一起学习一起努力!