Django models 复杂模型的非平凡django序列化程序

Django models 复杂模型的非平凡django序列化程序,django-models,django-serializer,Django Models,Django Serializer,在我用Java编写了多年代码之后,我在工作中得到了一个有趣的项目,该项目将使用python django rest框架进行开发 我有一个复杂的模型,有很多关系,我想基于一个JSON请求在DB中创建实体。请参阅随附的我的DB型号屏幕截图 我的目标是在DB中创建新项目,在DB中我有一组公司,自由职业者可以向公司的项目提出建议 我希望获得一个JSON请求,该请求包含: 公司id(已在DB中) 自由职业者:电子邮件、姓名等 项目信息:名称、年份、说明->这将是新创建的,除非名称已存在于数据库中 任务清单

在我用Java编写了多年代码之后,我在工作中得到了一个有趣的项目,该项目将使用python django rest框架进行开发

我有一个复杂的模型,有很多关系,我想基于一个JSON请求在DB中创建实体。请参阅随附的我的DB型号屏幕截图

我的目标是在DB中创建新项目,在DB中我有一组公司,自由职业者可以向公司的项目提出建议

我希望获得一个JSON请求,该请求包含:

  • 公司id(已在DB中)
  • 自由职业者:电子邮件、姓名等
  • 项目信息:名称、年份、说明->这将是新创建的,除非名称已存在于数据库中
  • 任务清单
  • 请求列表
  • 当我在服务器上收到请求时,我想首先检查自由职业者是否存在(我通过电子邮件查找),然后使用他的ID或创建一个新的自由职业者实体,然后创建一个新的项目条目(我还可以检查我没有重复的姓名和年份-在这种情况下抛出一个错误)并使用相关FK和相同的请求为项目创建新任务

    根据我使用JEE的经验,我只需要创建一个反映JSON的DTO,并且只需要一个服务层来检查条件并相应地创建对象

    我有点不知道如何使用django,我看到的所有教程都提供了一种非常清晰的方法,可以为一个几乎1:1映射到JSON(DTO)的DB模型执行简单的CRUD操作,那里几乎没有业务逻辑

    有人能告诉我怎么避开这个吗?也许你有什么好的例子可以参考


    谢谢。

    各个序列化程序用于字段验证,因此没有恶意数据

    from django.db import transaction
    from rest_framework import serializers
    
    class FreeLancerSerializer(serializers.ModelSerializer):
    
        class Meta(object):
            model = FreeLancer
            fields = ('email', '...other field')
    
    
    class TasksSerializer(serializers.ModelSerializer):
    
        class Meta(object):
            model = Task
            fields = (..task model fields..)
    
    
    class RequestsSerializer(serializers.ModelSerializer):
    
        class Meta(object):
            model = Request
            fields = (..request model fields..)
    
    
    class ProjectSerializer(serializers.ModelSerializer):
        freelancer = FreeLancerSerializer()
        tasks = TasksSerializer(many=True)
        requests = RequestsSerializer(many=True)
    
        class Meta(object):
            model = Project
            fields = ('project_name', ..project model fields .., 'freelancer', 'tasks', 'requests')
    
            #project_name validation
            def validate_project_name(self, project_name):
                if Project.objects.filter(project_name=project_name).exists():
                    raise serializers.ValidationError("project with this name already exists.")
                return project_name
    
            @transaction.atomic #will rollback all the transactions if something fails
            def create(self, validated_data):
                freelancer = validated_data.pop('freelancer')
                tasks_data = validated_data.pop('tasks')
                requests_data = validated_data.pop('requests')
                # gets the freelancer if alread created else creates it.
                freelancer_obj = FreeLancer.objects.get_or_create(
                    email = freelancer.get('email'),
                    defaults = freelancer
                )
    
                validated_data['freelancer'] = freelancer_obj
                project = super(ProjectSerializer, self).create(validated_data)
    
                #Validates tasks data and creates tasks
                try:
                    task_objects = TasksSerializer(data=tasks_data, many=True)
                    task_objects.is_valid(raise_exception=True)
                    tasks = task_objects.save()
                    project.tasks.add(tasks); #add tasks to project.
                except:
                    raise serializers.ValidationError("tasks not valid.")
    
                #Validates requests data and creates requests
                try:
                    request_objects = RequestsSerializer(data=requests_data, many=True)
                    request_objects.is_valid(raise_exception=True)
                    requests = request_objects.save()
                    project.requests.add(requests); #add requests to project.
                except:
                    raise serializers.ValidationError("requests not valid.")
    
                project.save()
    
                return project
    
    注:还需要模型级验证,如自由职业者的
    电子邮件
    必须是
    唯一的
    ,以及
    名称
    必须分别是
    唯一的
    项目模型等等

    PS:您可能需要做一些更改