Django序列化程序中的覆盖put方法

时间:2019-02-15 04:58:28

标签: django django-rest-framework

我使用嵌套的序列化程序并成功重写了create方法以保存到模型。现在,我必须通过重写update方法对put方法执行相同的操作。我收到如下错误:

key error for 'short_name'

我的序列化器:

class WorkflowSerializer(serializers.ModelSerializer):
  levels = WorkflowLevelSerializer(many=True)

  class Meta:
    model = Workflow
    fields = ('name', 'description', 'levels')

 def create(self, validated_data):
    levels = validated_data.pop('levels')
    workflow = Workflow.objects
 .create(**validated_data,tenant=self.context['request'].user.tenant)

    for index, level in enumerate(levels):
        level_var = WorkflowLevel()
        level_var.workflow = workflow
        level_var.level = level['level']
        level_var.operation=level['operation']
        level_var.save()

        for permission in self.initial_data['levels'][index] 
        ['workflow_permissions']:
            permission_obj = WorkflowPermission.objects
         .filter(short_name=permission['short_name']).first()
            workflowlevelpermission = WorkflowLevelPermission()
            workflowlevelpermission.level = level_var
            workflowlevelpermission.permission=permission_obj
            workflowlevelpermission.save()


    return workflow

 def update(self, instance, validated_data):
    print(validated_data)
    levels = validated_data.get('levels')
    instance.name = validated_data.get('name', instance.name)
    instance.desciption = validated_data.get('description', 
    instance.description)
    instance.tenant = self.context['request'].user.tenant
    print("LEVELS",levels)


    for index, level in enumerate(levels):
        level_var = 
     WorkflowLevel.objects.filter(workflow=instance).first()
        level_var.level = level['level']
        level_var.operation=level['operation']
        level_var.save()

        print("Workflow Permissions",validated_data['levels'][index] 
     ['workflow_permissions'])

        for permission in validated_data['levels'][index] 
       ['workflow_permissions']:
            permission_obj = WorkflowPermission.objects
       .filter(short_name=permission['short_name']).first()
            workflowlevelpermission = WorkflowLevelPermission()
            workflowlevelpermission.level = level_var
            workflowlevelpermission.permission=permission_obj
            workflowlevelpermission.save()


    return instance

有人可以建议编写此更新方法的正确方法吗?

1 个答案:

答案 0 :(得分:0)

此方法有效:

def update(self, instance, validated_data):
    levels = self.initial_data.get('levels')
    categories = self.initial_data['selectedCategories']
    instance.name = validated_data.get('name', instance.name)
    instance.description = validated_data.get('description', instance.description)
    instance.tenant = self.context['request'].user.tenant
    levels_it_has = []
    workflows = WorkflowLevel.objects.filter(workflow=instance).order_by('level')

    for workflow in workflows:
        levels_it_has.append(workflow.level)

    for index, level in enumerate(levels):
        # Check if editing existing level
        if WorkflowLevel.objects.filter(workflow=instance,level=level['level']).exists():
             level_var = WorkflowLevel.objects.filter(workflow=instance,level=level['level']).first()
             level_var.level = level['level']
             level_var.operation=level['operation']
             level_var.save()
        #If creating new Level 
        else:
            level_var = WorkflowLevel()
            level_var.workflow = instance
            level_var.level = level['level']
            level_var.operation = level['operation']
            level_var.save()

        ########### Level Permissions ############3#########

        for permission in level['workflow_permissions']:
            permission_obj = WorkflowPermission.objects.filter(short_name=permission['short_name']).first()
            permissions_in_level = []
            level_permissions = WorkflowLevelPermission.objects.filter(level=level_var,permission=permission_obj,level__workflow=instance).select_related('permission')
            for perm in level_permissions:
                permissions_in_level.append(perm.permission.short_name)
            if not level_permissions.exists():
                permission = WorkflowLevelPermission()
                permission.level = level_var
                permission.permission = permission_obj
                permission.save() 
            new_perms=[]
            level_permissions = WorkflowLevelPermission.objects.filter(level=level_var,level__workflow=instance).select_related('permission')
            for perm in level_permissions:
                new_perms.append(perm.permission.short_name)

    ####################### DELETE PERMISSIONS ####################################

            if len(new_perms) > len(level['workflow_permissions']):
                short_names = []
                for perm in level['workflow_permissions']:
                    short_names.append(perm['short_name'])
                perm_to_delete = [item for item in new_perms if item not in short_names]
                workflow_permission_to_delete = WorkflowLevelPermission.objects.filter(level=level_var,level__workflow=instance,permission__short_name__in=perm_to_delete)          
                workflow_permission_to_delete.delete()


    ####################### DELETE LEVELS ####################################


    if len(levels_it_has) > len(levels):
        level_numbers = []
        for lev in levels:
            level_numbers.append(lev['level'])
        level_to_delete = [item for item in levels_it_has if item not in level_numbers]
        workflow_level_to_delete = WorkflowLevel.objects.filter(workflow=instance,level__in=level_to_delete)          
        workflow_level_to_delete.delete()

    ##########################################################################

    for category in categories:
        if not WorkflowCategoryLink.objects.filter(workflow=instance,target_type__short_name=category['short_name']):
            workflow_category = WorkflowCategory.objects.filter(short_name=category['short_name']).first()
            workflow_category_link = WorkflowCategoryLink()
            workflow_category_link.workflow=instance
            workflow_category_link.target_type=workflow_category
            workflow_category_link.save()    

    new_categories = []
    categories_db = WorkflowCategoryLink.objects.filter(workflow=instance)
    for cat in categories_db:
        new_categories.append(cat.target_type.short_name)

    ######################## DELETE CATEGORIES ##############################

    if len(new_categories)> len(categories):
        short_names = []
        for cat in categories:
            short_names.append(cat['short_name'])
            category_to_delete = [item for item in new_categories if item not in short_names]
            category_link_to_delete = WorkflowCategoryLink.objects.filter(workflow=instance,target_type__short_name__in=category_to_delete)          
            category_link_to_delete.delete()

    if len(categories) == 0:
        WorkflowCategoryLink.objects.filter(workflow=instance).delete()

    instance.save()
    return instance