美文网首页
在django rest framework的model序列化时

在django rest framework的model序列化时

作者: 万州客 | 来源:发表于2021-01-27 21:47 被阅读0次

今天作发布单历史和服务器历史的API时,遇到的问题。即,有的字段有可能有None,比如发布单历史,在正式发布单的新建和编译时,env的字段是空的。如果一视同仁的序列化,就会报错。

一,model字段

from django.db import models
from .base_models import BaseModel
from .env_models import Env
from .release_models import Release, ReleaseStatus
from .server_models import Server

DEPLOY_CHOICES = (
    ('deploy', '部署'),
    ('rollback', '回滚'),
)

OP_CHOICES = (
    ('deploy', '部署'),
    ('maintenance', '启停维护'),
)

ACTION_CHOICES = (
    ('fetch', '获取软件'),
    ('stop', '停止'),
    ('stop_status', '停止状态检测'),
    ('deploy', '部署'),
    ('rollback', '回滚'),
    ('start', '启动'),
    ('start_status', '启动状态检测'),
    ('health_check', '服务健康检测'),
)


# 发布单历史,记录发布单的生命周期,新建,编译,流转,部署,回滚部署
class ReleaseHistory(BaseModel):
    release = models.ForeignKey(Release,
                                related_name='ra_release_history',
                                blank=True,
                                null=True,
                                on_delete=models.SET_NULL,
                                verbose_name='发布单')
    env = models.ForeignKey(Env,
                            related_name="ra_release_history",
                            blank=True,
                            null=True,
                            on_delete=models.SET_NULL,
                            verbose_name="环境")
    deploy_status = models.ForeignKey(ReleaseStatus,
                                      related_name='ra_release_history',
                                      blank=True,
                                      null=True,
                                      on_delete=models.SET_NULL,
                                      verbose_name="发布单状态")
    deploy_type = models.CharField(max_length=255,
                                   choices=DEPLOY_CHOICES,
                                   blank=True,
                                   null=True,
                                   verbose_name="部署类型")
    log = models.TextField(verbose_name="日志内容")

    class Meta:
        db_table = 'ReleaseHistory'
        verbose_name = 'ReleaseHistory发布单历史'
        verbose_name_plural = 'ReleaseHistory发布单历史'


# 服务器变更历史,记录服务器上的部署,停止,回滚
class ServerHistory(BaseModel):
    server = models.ForeignKey(Server,
                               related_name='ra_server_history',
                               blank=True,
                               null=True,
                               on_delete=models.SET_NULL,
                               verbose_name='服务器')
    release = models.ForeignKey(Release,
                                related_name='ra_server_history',
                                blank=True,
                                null=True,
                                on_delete=models.SET_NULL,
                                verbose_name='发布单')
    env = models.ForeignKey(Env,
                            related_name="ra_server_history",
                            blank=True,
                            null=True,
                            on_delete=models.SET_NULL,
                            verbose_name="环境")
    op_type = models.CharField(max_length=255,
                               choices=OP_CHOICES,
                               blank=True,
                               null=True,
                               verbose_name="操作类型")
    action_type = models.CharField(max_length=255,
                                   choices=ACTION_CHOICES,
                                   blank=True,
                                   null=True,
                                   verbose_name="服务器操作类型")
    log = models.TextField(verbose_name="日志内容")

    class Meta:
        db_table = 'ServerHistory'
        verbose_name = 'ServerHistory服务器历史'
        verbose_name_plural = 'ServerHistory服务器历史'

从Model定义中可以看到,env,release这些字段都有可能为None
二,过滤器

from django_filters import OrderingFilter
from django_filters.rest_framework import FilterSet
from django_filters import filters
from cmdb.models import ReleaseHistory
from cmdb.models import ServerHistory


class ReleaseHistoryFilter(FilterSet):
    release = filters.CharFilter(field_name='release__name', lookup_expr='icontains',)
    begin_time = filters.DateTimeFilter(field_name='create_date', lookup_expr='gte',)
    end_time = filters.DateTimeFilter(field_name='create_date', lookup_expr='lte',)
    sort = OrderingFilter(fields=('create_date',))

    class Meta:
        model = ReleaseHistory
        fields = ['release', 'begin_time', 'end_time']


class ServerHistoryFilter(FilterSet):
    server = filters.CharFilter(field_name='server__name', lookup_expr='icontains',)
    begin_time = filters.DateTimeFilter(field_name='create_date', lookup_expr='gte',)
    end_time = filters.DateTimeFilter(field_name='create_date', lookup_expr='lte',)
    sort = OrderingFilter(fields=('create_date',))

    class Meta:
        model = ServerHistory
        fields = ['server', 'begin_time', 'end_time']

  • 在过滤时,发布单历史主要以发布单为过滤项,服务器历史主要以IP为过滤项。
    三,序列化
from rest_framework import serializers
from cmdb.models import ReleaseHistory
from cmdb.models import ServerHistory


class ReleaseHistorySerializer(serializers.ModelSerializer):
    env = serializers.CharField(source='env.name', default=None)
    release = serializers.CharField(source='release.name', default=None)
    create_user = serializers.CharField(source='create_user.username')

    class Meta:
        model = ReleaseHistory
        fields = '__all__'


class ServerHistorySerializer(serializers.ModelSerializer):
    server = serializers.CharField(source='server.name', default=None)
    env = serializers.CharField(source='env.name', default=None)
    release = serializers.CharField(source='release.name', default=None)
    create_user = serializers.CharField(source='create_user.username')

    class Meta:
        model = ServerHistory
        fields = '__all__'

  • env = serializers.CharField(source='env.name', default=None)这里的default=None参数是关键,如果不带这个参数,就会出现以下的错误:
    AttributeError: Got AttributeError when attempting to get a value for fieldenv_nameon serializerReleaseHistorySerializer. The serializer field might be named incorrectly and not match any attribute or key on theReleaseHistoryinstance. Original exception text was: 'NoneType' object has no attribute 'name'.
    四,ListView
from rest_framework.generics import ListAPIView
from cmdb.models import ReleaseHistory
from cmdb.models import ServerHistory
from .filters import ReleaseHistoryFilter
from .filters import ServerHistoryFilter
from .serializers import ReleaseHistorySerializer
from .serializers import ServerHistorySerializer


from utils.ret_code import *


class ReleaseHistoryListView(ListAPIView):
    queryset = ReleaseHistory.objects.all()
    serializer_class = ReleaseHistorySerializer
    filter_class = ReleaseHistoryFilter

    def get(self, request, *args, **kwargs):
        res = super().get(self, request, *args, **kwargs)
        return_dict = build_ret_data(OP_SUCCESS, res.data)
        return render_json(return_dict)


class ServerHistoryListView(ListAPIView):
    queryset = ServerHistory.objects.all()
    serializer_class = ServerHistorySerializer
    filter_class = ServerHistoryFilter

    def get(self, request, *args, **kwargs):
        res = super().get(self, request, *args, **kwargs)
        return_dict = build_ret_data(OP_SUCCESS, res.data)
        return render_json(return_dict)


  • 常规套路,指定查询集,序列化,过滤器就好,然后,统一自定义返回值。
    五,URL路由
from django.urls import path
from . import views

app_name = "history"

urlpatterns = [
    path('release/', views.ReleaseHistoryListView.as_view(), name='release'),
    path('server/', views.ServerHistoryListView.as_view(), name='server'),

]

六,POSTMAN测试


2021-01-27 21_46_40-悬浮球.png

http://localhost:8000/history/release/?release=20210126194249879220CA

{
    "code": 0,
    "message": "操作成功",
    "data": {
        "count": 9,
        "next": null,
        "previous": null,
        "results": [
            {
                "id": 60,
                "env": null,
                "release": "20210126194249879220CA",
                "create_user": "admin",
                "name": "9e07a326-5fcb-11eb-a19f-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-26T19:42:49.929118+08:00",
                "create_date": "2021-01-26T19:42:49.929118+08:00",
                "base_status": true,
                "deploy_type": null,
                "log": "Create",
                "deploy_status": 22
            },
            {
                "id": 61,
                "env": null,
                "release": "20210126194249879220CA",
                "create_user": "admin",
                "name": "b0aca356-5fcb-11eb-9fb9-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-26T19:43:21.205546+08:00",
                "create_date": "2021-01-26T19:43:21.205546+08:00",
                "base_status": true,
                "deploy_type": null,
                "log": "Building",
                "deploy_status": 23
            },
            {
                "id": 62,
                "env": null,
                "release": "20210126194249879220CA",
                "create_user": "admin",
                "name": "e2d8882c-5fcb-11eb-90c5-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-26T19:44:45.381243+08:00",
                "create_date": "2021-01-26T19:44:45.381243+08:00",
                "base_status": true,
                "deploy_type": null,
                "log": "Build",
                "deploy_status": 25
            },
            {
                "id": 63,
                "env": "dev",
                "release": "20210126194249879220CA",
                "create_user": "admin",
                "name": "ff36723b-5fcb-11eb-a874-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-26T19:45:32.982678+08:00",
                "create_date": "2021-01-26T19:45:32.982678+08:00",
                "base_status": true,
                "deploy_type": null,
                "log": "Ongoing",
                "deploy_status": 27
            },
            {
                "id": 64,
                "env": "dev",
                "release": "20210126194249879220CA",
                "create_user": "admin",
                "name": "121d5041-5fcc-11eb-a04a-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-26T19:46:04.706438+08:00",
                "create_date": "2021-01-26T19:46:04.706438+08:00",
                "base_status": true,
                "deploy_type": "deploy",
                "log": "Success",
                "deploy_status": 28
            },
            {
                "id": 65,
                "env": "dev",
                "release": "20210126194249879220CA",
                "create_user": "admin",
                "name": "93e08010-5fcc-11eb-85d2-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-26T19:49:42.399962+08:00",
                "create_date": "2021-01-26T19:49:42.399962+08:00",
                "base_status": true,
                "deploy_type": null,
                "log": "Ongoing",
                "deploy_status": 27
            },
            {
                "id": 66,
                "env": "dev",
                "release": "20210126194249879220CA",
                "create_user": "admin",
                "name": "a0c503fd-5fcc-11eb-b9b8-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-26T19:50:04.060525+08:00",
                "create_date": "2021-01-26T19:50:04.060525+08:00",
                "base_status": true,
                "deploy_type": "rollback",
                "log": "Success",
                "deploy_status": 28
            },
            {
                "id": 67,
                "env": "dev",
                "release": "20210126194249879220CA",
                "create_user": "admin",
                "name": "a2a5af61-5fce-11eb-bc32-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-26T20:04:26.178675+08:00",
                "create_date": "2021-01-26T20:04:26.178675+08:00",
                "base_status": true,
                "deploy_type": null,
                "log": "Ongoing",
                "deploy_status": 27
            },
            {
                "id": 68,
                "env": "dev",
                "release": "20210126194249879220CA",
                "create_user": "admin",
                "name": "b02ed13f-5fce-11eb-99cb-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-26T20:04:48.897537+08:00",
                "create_date": "2021-01-26T20:04:48.897537+08:00",
                "base_status": true,
                "deploy_type": "deploy",
                "log": "Success",
                "deploy_status": 28
            }
        ]
    }
}

http://localhost:8000/history/server/?server=192.168.1.211

{
    "code": 0,
    "message": "操作成功",
    "data": {
        "count": 41,
        "next": "http://localhost:8000/history/server/?currentPage=2&server=192.168.1.211",
        "previous": null,
        "results": [
            {
                "id": 4,
                "server": "192.168.1.211",
                "env": "dev",
                "release": "20210124230452791843DX",
                "create_user": "admin",
                "name": "1f841979-5f12-11eb-8f06-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-25T21:35:00.794408+08:00",
                "create_date": "2021-01-25T21:35:00.794408+08:00",
                "base_status": true,
                "op_type": "deploy",
                "action_type": "fetch",
                "log": "APP_NAME: go-demo prepare success."
            },
            {
                "id": 5,
                "server": "192.168.1.211",
                "env": "dev",
                "release": "20210124230452791843DX",
                "create_user": "admin",
                "name": "22470a81-5f12-11eb-a81a-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-25T21:35:05.419020+08:00",
                "create_date": "2021-01-25T21:35:05.419020+08:00",
                "base_status": true,
                "op_type": "deploy",
                "action_type": "stop",
                "log": "18729\nAPP_NAME: go-demo is success stop."
            },
            {
                "id": 7,
                "server": "192.168.1.211",
                "env": "dev",
                "release": "20210124230452791843DX",
                "create_user": "admin",
                "name": "23499475-5f12-11eb-80ae-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-25T21:35:07.118277+08:00",
                "create_date": "2021-01-25T21:35:07.118277+08:00",
                "base_status": true,
                "op_type": "deploy",
                "action_type": "stop_status",
                "log": "APP_NAME: go-demo is success on stop."
            },
            {
                "id": 10,
                "server": "192.168.1.211",
                "env": "dev",
                "release": "20210124230452791843DX",
                "create_user": "admin",
                "name": "243a35dc-5f12-11eb-bf37-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-25T21:35:08.705017+08:00",
                "create_date": "2021-01-25T21:35:08.705017+08:00",
                "base_status": true,
                "op_type": "deploy",
                "action_type": "deploy",
                "log": "APP_NAME: go-demo deploy success."
            },
            {
                "id": 12,
                "server": "192.168.1.211",
                "env": "dev",
                "release": "20210124230452791843DX",
                "create_user": "admin",
                "name": "26d0b5cf-5f12-11eb-9779-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-25T21:35:13.038520+08:00",
                "create_date": "2021-01-25T21:35:13.038520+08:00",
                "base_status": true,
                "op_type": "deploy",
                "action_type": "start",
                "log": "APP_NAME:  go-demo is start success in 3 seconds. \\n"
            },
            {
                "id": 14,
                "server": "192.168.1.211",
                "env": "dev",
                "release": "20210124230452791843DX",
                "create_user": "admin",
                "name": "27bd0f32-5f12-11eb-99fe-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-25T21:35:14.604533+08:00",
                "create_date": "2021-01-25T21:35:14.604533+08:00",
                "base_status": true,
                "op_type": "deploy",
                "action_type": "start_status",
                "log": "APP_NAME: go-demo is success on running."
            },
            {
                "id": 16,
                "server": "192.168.1.211",
                "env": "dev",
                "release": "20210124230452791843DX",
                "create_user": "admin",
                "name": "28b15c5d-5f12-11eb-ab19-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-25T21:35:16.216333+08:00",
                "create_date": "2021-01-25T21:35:16.216333+08:00",
                "base_status": true,
                "op_type": "deploy",
                "action_type": "health_check",
                "log": "APP_NAME: go-demo is success health."
            },
            {
                "id": 18,
                "server": "192.168.1.211",
                "env": "dev",
                "release": "20210124230452791843DX",
                "create_user": "admin",
                "name": "e427c820-5f14-11eb-b529-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-25T21:54:49.688088+08:00",
                "create_date": "2021-01-25T21:54:49.688088+08:00",
                "base_status": true,
                "op_type": "deploy",
                "action_type": "fetch",
                "log": "APP_NAME: go-demo prepare success."
            },
            {
                "id": 20,
                "server": "192.168.1.211",
                "env": "dev",
                "release": "20210124230452791843DX",
                "create_user": "admin",
                "name": "e6f84fbf-5f14-11eb-8104-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-25T21:54:54.412564+08:00",
                "create_date": "2021-01-25T21:54:54.412564+08:00",
                "base_status": true,
                "op_type": "deploy",
                "action_type": "stop",
                "log": "21044\nAPP_NAME: go-demo is success stop."
            },
            {
                "id": 22,
                "server": "192.168.1.211",
                "env": "dev",
                "release": "20210124230452791843DX",
                "create_user": "admin",
                "name": "e7f6b410-5f14-11eb-9fa8-1cbfc0db9238",
                "description": null,
                "update_date": "2021-01-25T21:54:56.094383+08:00",
                "create_date": "2021-01-25T21:54:56.094383+08:00",
                "base_status": true,
                "op_type": "deploy",
                "action_type": "stop_status",
                "log": "APP_NAME: go-demo is success on stop."
            }
        ]
    }
}

相关文章

网友评论

      本文标题:在django rest framework的model序列化时

      本文链接:https://www.haomeiwen.com/subject/tclzzktx.html