Django DRF在創建父表數據時同時將子表數據一同創建

1、用於測試的模型

# 父表模型
class Auth(SoftDeleteModel, BaseModel):
    auth_type = models.CharField(max_length=255, verbose_name='權限名稱')

    class Meta:
        db_table = 'A_Auth_Table'
        verbose_name = '權限組表'
        verbose_name_plural = verbose_name

# 子表模型
class AuthPermission(SoftDeleteModel, BaseModel):
    object_name = models.CharField( max_length=255, verbose_name='功能名稱')
    object_name_cn = models.CharField(max_length=255, verbose_name='功能名稱-中文')
    # 外鍵指向 Auth
    auth = models.ForeignKey(Auth, on_delete=models.PROTECT, verbose_name='權限組', related_name='auth_permissions')
    auth_list = models.NullBooleanField(default=False, verbose_name='查看')
    auth_create = models.NullBooleanField(default=False, verbose_name='新增')
    auth_update = models.NullBooleanField(default=False, verbose_name='修改')
    auth_destroy = models.NullBooleanField(default=False, verbose_name='刪除')

    class Meta:
        db_table = 'A_AuthPermission_Table'
        verbose_name = '權限菜單表'
        verbose_name_plural = verbose_name

2、用於測試序列化器

from rest_framework import serializers
from rest_framework.serializers import SerializerMethodField
from rest_framework.validators import UniqueValidator
from base.serializers import BaseModelSerializer
from rest_framework.utils import model_meta
from .models import *
import time
import datetime
import threading



# 新增權限菜單約束使用
class AddAuthPermissionSerializer(serializers.ModelSerializer):

    class Meta:
        model = AuthPermission
        fields = ['id','object_name', 'object_name_cn','auth_list','auth_create','auth_update','auth_destroy']

def del_worker(datas):
    for item in datas:
        item.delete()
def save_worker(instance, datas):
    for item in datas:
        AuthPermission.objects.create(auth=instance, **item)

# 新增權限使用
class AddAuthSerializer(serializers.ModelSerializer, BaseModelSerializer):
    auth_type = serializers.CharField(label="權限名稱", help_text="權限名稱", required=True, allow_blank=False,
                                       validators=[UniqueValidator(queryset=Auth.objects.all(), message="該權限已經存在")])
    auth_permissions = AddAuthPermissionSerializer(many=True)

    class Meta:
        model = Auth
        exclude = ('deleted',)

    def create(self, validated_data):
        auth_permissions_data = validated_data.pop('auth_permissions')
        auth_per = Auth.objects.create(**validated_data)
        # 創建權限菜單的方法
        for item in auth_permissions_data:
            AuthPermission.objects.create(auth=auth_per, **item)
        return auth_per

    def update(self, instance, validated_data):
        # print('查看auth_permissions:', validated_data.get('auth_permissions'))
        if validated_data.get('auth_permissions'):
            auth_permissions_data = validated_data.pop('auth_permissions')
            # 修改時創建權限菜單的方法
            need_dels = AuthPermission.objects.filter(auth_id=instance.id)
            # for item in need_dels:
            #     item.delete()
            # for item in auth_permissions_data:
            #     # print('查看:', item)
            #     # print('查看id:', item.get('id'))
            #     AuthPermission.objects.create(auth=instance, **item)
            # 開多線程優化代碼
            del_work = threading.Thread(target=del_worker,args=(need_dels,))
            del_work.start()
            save_work = threading.Thread(target=save_worker,args=(instance,auth_permissions_data,))
            save_work.start()
            save_work.join()

        # 繼承自父類的方法
        info = model_meta.get_field_info(instance)
        for attr, value in validated_data.items():
            if attr in info.relations and info.relations[attr].to_many:
                field = getattr(instance, attr)
                field.set(value)
            else:
                setattr(instance, attr, value)
        instance.save()
        return instance


# 返回權限使用
class ReturnAuthSerializer(serializers.ModelSerializer, BaseModelSerializer):
    auth_permissions = AddAuthPermissionSerializer(read_only=True, many=True)

    class Meta:
        model = Auth
        exclude = ('deleted',)

3、用於測試的視圖

class AuthViewset(ModelViewSet):
    '''
    修改局部數據
    create:  創建權限
    retrieve:  檢索某個權限
    update:  更新權限
    destroy:  刪除權限
    list:  獲取權限列表
    '''
    queryset = Auth.objects.all().order_by('-updated')
    authentication_classes = (JWTAuthentication,)
    permission_classes = [BaseAuthPermission, ]
    throttle_classes = [VisitThrottle]
    serializer_class = ReturnAuthSerializer
    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter,)
    search_fields = ('auth_type',)
    ordering_fields = ('updated', 'sort_time', 'created',)
    pagination_class = Pagination

    def get_serializer_class(self):
        if self.action in ['create', 'update', 'partial_update']:
            return AddAuthSerializer
        return ReturnAuthSerializer

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        # 刪除權限子表
        auths = AuthPermission.objects.filter(auth_id=instance.id)
        for item in auths:
            item.delete()
        self.perform_destroy(instance)
        return Response(status=status.HTTP_204_NO_CONTENT)

4、使用postman測試

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章