Django 事务 多表操作

事务

事务:是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元);

事务的四大特性:

1 、原子性 
事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做 
2 、一致性 
事 务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。 
3 、隔离性 
一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。 
4 、持续性 
也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。 

 

完整语法结构:

from django.db import transaction  
try:
    with transaction.atomic():
        dosomething_1()
        dosomething_2()
        
except Exception as e:
   # 事务出错,将会自动回滚,在这里可以做事务失败后的其他操作
    ...
else:
    ...
finally:
    ...

事务处理多表

# 注册
class RegisterAPIView(APIView):
    """{{"mobile":"13764112557","password":"zzz12365","name":"zzz","team_position":1,"team_id":1}"""

    def post(self, request, *args, **kwargs):
        ser = serializers.UserRegisterSerilaizer(data=request.data)
        if ser.is_valid():
            try:
                # 开启事务
                with transaction.atomic():
                    user_list = []
                    user_obj = ser.save()
                    user_id = user_obj.pk
                    team_id = request.data.get("team_id")
                    users_obj = task_models.User_Team(team_id_id=team_id, user_id_id=user_id)
                    user_list.append(users_obj)
                    task_models.User_Team.objects.bulk_create(user_list)
            except Exception as e:
                return Response({"status": 1, "msg": "创建失败,请稍后再试"})
            else:
                # 当是组长时修改三张表
                if request.data["team_position"] == 0:
                    team_id = request.data["team_id"]
                    users_obj = task_models.TaskTeam.objects.filter(team_type=team_id).update(leader=user_obj.pk)
                    return Response({"status": 0, "msg": "创建成功", "result": users_obj})
                else:
                    # 当是组员则添加数据不修改表数据
                    user_data = serializers.UserRegisterSerilaizer(user_obj).data
                    return Response({"status": 0, "msg": "创建成功", "result": user_data})
        else:
            return Response({'status': 1, 'msg': ser.errors})


# 运维人员删改查
class Personal_information(APIView):
    # 1.查
    def get(self, request, *args, **kwargs):
        user_obj = models.User.objects.all()
        ser_data = serializers.Personal_informationModelSerializer(user_obj, many=True).data
        data_list = []
        for i in ser_data:
            if i["name"] == None and i["mobile"] == None and i["team_ids"] == []:
                pass
            else:
                id = i["id"]
                name = i["name"]
                mobile = i["mobile"]
                team_ids = (i["team_ids"][0]["team_name"])
                data_list.append({"id": id, "name": name, "mobile": mobile, "team_ids": team_ids})
        return Response({"status": 0, "res": data_list})

    # 2.改(id,mobile,username,team_position,team_id)
    def put(self, request, *args, **kwargs):
        """
        http://192.168.0.183:8001/api/user/personal_information/
        单改:{"user_id": 78,"mobile":13817997884,"username":13817997882,"team_position":1,"team_id":1}
        群该:[{"user_id": 78,"mobile":13817997884,"username":13817997882,"team_position":1,"team_id":1},{"user_id": 79,"mobile":13817997885,"username":13817997883,"team_position":1,"team_id":1}]

        """
        try:
            # 开启事务
            with transaction.atomic():
                if isinstance(request.data, dict):
                    many = False
                    user_id = request.data.get('user_id')
                    mobile = request.data.get('mobile')
                    username = request.data.get('username')
                    team_position = request.data.get('team_position')
                    team_id = request.data.get('team_id')
                    if re.match('^1[3-9][0-9]{9}$', str(mobile)):
                        userinfo = models.User.objects.filter(pk=user_id, mobile=mobile)
                        print(userinfo)
                        if userinfo.exists():
                            return Response({"status": 1, "msg": "手机号已存在"})
                        else:
                            models.User.objects.filter(pk=user_id).update(mobile=mobile, username=username)
                            task_models.User_Team.objects.filter(user_id_id=user_id).update(team_id_id=team_id)
                            # 当是组长时修改三张表
                            if team_position == 0:
                                users_obj = task_models.TaskTeam.objects.filter(team_type=team_id).update(
                                    leader=user_id)
                                return Response({"status": 0, "msg": "ok"})
                            else:
                                # 当是组员则添加数据不修改表数据
                                users_obj = serializers.Personal_informationModelSerializer(
                                    models.User.objects.all()).data
                                return Response({"status": 0, "msg": "ok"})
                    else:
                        print('手机号不合法')
                    return Response({"status": 0})
                elif isinstance(request.data, list):
                    many = True
                    for k in [request.data]:
                        for v in k:
                            user_id = v.get('user_id')
                            mobile = v.get('mobile')
                            username = v.get('username')
                            team_position = v.get('team_position')
                            team_id = v.get('team_id')
                            if re.match('^1[3-9][0-9]{9}$', str(mobile)):
                                userinfo = models.User.objects.filter(pk=user_id, mobile=mobile)
                                if userinfo.exists():
                                    return Response({"status": 1, "msg": "手机号已存在"})
                                else:
                                    models.User.objects.filter(pk=user_id).update(mobile=mobile, username=username)
                                    task_models.User_Team.objects.filter(user_id_id=user_id).update(team_id_id=team_id)
                                    # 当是组长时修改三张表
                                    if team_position == 0:
                                        users_obj = task_models.TaskTeam.objects.filter(team_type=team_id).update(
                                            leader=user_id)
                                        return Response({"status": 0, "msg": "创建成功", "result": users_obj})
                                    else:
                                        # 当是组员则添加数据不修改表数据
                                        users_obj = serializers.Personal_informationModelSerializer(
                                            models.User.objects.all()).data
                                        return Response({"status": 0, "msg": "创建成功", "result": users_obj})
                            else:
                                print('手机号不合法')
                        return Response({"status": 0})
        except Exception as e:
            return Response({"status": 1, "msg": "创建失败,请稍后再试"})

    # 3.删
    # 单删:url有pk
    # 群删:数据包有pks   |  {"pks": [1, 2, 3]}
    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        if pk:
            pks = [pk]
        else:
            pks = request.data.get('pks')
        if models.User.objects.filter(pk__in=pks, is_enable=1).update(is_enable=0):
            return Response({'status': 0, 'msg': '删除成功'})
        return Response({'status': 1, 'msg': '删除失败'})
View
# 2.注册
class UserRegisterSerilaizer(serializers.ModelSerializer):
    team_positions = serializers.CharField(source="get_team_position_display", read_only=True)
    team_id = serializers.IntegerField(write_only=True, error_messages={"required": "缺少班组信息"})
    team_ids = serializers.SerializerMethodField()

    class Meta:
        model = models.User
        fields = ["name",'mobile', 'username', "team_positions", "team_position", "team_id", "team_ids"]
        extra_kwargs = {
            'username': {
                'required': True,
                'read_only': True,
                'error_messages': {
                    "required": '缺少用户名'
                }
            },
            'password': {
                'required': True,
                'max_length': 18,
                'min_length': 8,
                'error_messages': {
                    "required": '缺少密码',
                    'max_length': '密码不能超过18位',
                    'min_length': '密码不能少于8位'
                }
            },
        }

    def get_team_ids(self, obj):
        query_set = obj.taskteam_set.filter(is_delete=False)
        data_list = [{"team_name": team_obj.team_name} for team_obj in query_set]
        return data_list

    def validate(self, attrs):
        mobile = attrs.get('mobile')
        # 验证码通过
        if re.match('^1[3-9][0-9]{9}$', mobile):
            attrs['username'] = mobile  # 把用户的名字设成手机号
            return attrs
        else:
            raise ValidationError('手机号不合法')

    # 重写create方法
    def create(self, validated_data):
        # 不入库之前删除班组id
        del validated_data["team_id"]
        user = models.User.objects.create_user(**validated_data)
        return user


# 3.查表是运维人员
class Personal_informationModelSerializer(serializers.ModelSerializer):
    team_id = serializers.IntegerField(write_only=True, error_messages={"required": "缺少班组信息"})
    team_ids = serializers.SerializerMethodField()

    class Meta:
        model = models.User
        fields = ["id", "name", "mobile", "team_id", "team_ids"]
    def validate(self, attrs):
        mobile = attrs.get('mobile')
        user_id = attrs.get('id')
        # 验证码通过
        if re.match('^1[3-9][0-9]{9}$', mobile):
            userinfo = models.User.objects.filter(pk=user_id, mobile=mobile)
            if userinfo.exists():
                print("yes,we have this email")
            else:
                print("sorry,email is not register")
        else:
            raise ValidationError('手机号不合法')

    def get_team_ids(self, obj):
        query_set = obj.taskteam_set.filter(is_delete=False)
        data_list = [{"team_name": team_obj.team_name} for team_obj in query_set]
        return data_list
serializers

 

posted @ 2020-12-25 16:08  zhw_sylvia  阅读(229)  评论(0编辑  收藏  举报