复杂模型的非平凡django序列化器 [英] non trivial django serializer for a complex model

查看:54
本文介绍了复杂模型的非平凡django序列化器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

After many years I code with Java, I got an interesting project at work to be developed using python django rest framework.

我有一个具有许多关系的复杂模型,在该模型中,我想基于一个JSON请求在数据库中创建实体.请参考我的数据库模型的屏幕截图.

I have a complex model, with many relations, in which I want to create entities in DB based on one JSON request. Please refer to attached screenshot of my DB model.

我的目标是在数据库中建立我的公司的数据库中创建新项目,并且自由职业者可以向公司的项目提出建议.

My goal is to create new projects in the DB where I have set of companies in DB and a freelancer can suggest to a project of the company.

我想要一个包含以下内容的JSON请求

I would like to get a JSON request that contains:

  1. 公司ID(已经在数据库中)
  2. 自由职业者:电子邮件,姓名等...
  3. 项目信息:名称,年份,描述->这将是新创建的,除非名称已经存在于数据库中
  4. 任务列表
  5. 请求列表

当我在服务器上收到请求时,我想先检查自由职业者是否存在(我通过电子邮件查找),然后使用其ID或创建一个新的自由职业者实体,然后创建一个新的Project条目(我也可以检查我没有名字和年份的重复-在这种情况下会抛出错误),并使用相关的FK为项目创建新任务,并为Requests创建相同的任务.

When I get the request on the server, I would like to check first if the freelancer exists (I lookup by email) then use his ID or create a new freelancer entity, then create a new Project entry (I can also check that I don't have duplicate by name and year - in such case throw an error) and create new tasks for the project with the relevant FK and same for Requests.

根据我在JEE方面的经验,我将简单地创建一个反映JSON的DTO,并将仅具有一个用于检查条件并相应地创建对象的服务层.

My experience with JEE, I would simply create a DTO that reflects the JSON and will just have a service layer that checks the condition and creates accordingly the objects.

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

I am a bit lost how to do it with django, all tutorials I see provide very clear way how to do simple CRUD operations for a DB model that is mapped almost 1 to 1 to the JSON (DTO), there is almost no business logic there.

有人可以让我知道如何解决这个问题吗?也许您有什么好的例子可以参考?

Could someone please let me know how to get around this? maybe you have any good example you can refer?

谢谢.

推荐答案

单独的序列化程序用于字段验证,因此没有恶意数据.

The individual serializers are used for field validation, so that there is no malicious data.

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

注意:还需要模型级别的验证,例如自由职业者的 email 必须是 unique ,而 name 必须是 unique项目模型等等.

Note : Model level validations will also be needed like email has to be unique for freelancer and name has to be unique project model respectively and so on.

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

PS : there might be some changes you might need to to do.

这篇关于复杂模型的非平凡django序列化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆