• 一.5.序列化应用之服务器制造厂与型号app功能


     1.环境准备:

     (python36env) [vagrant@CentOS7 apps]$ django-admin startapp manufacturer

    (1)激活:'manufacturer.apps.ManufacturerConfig'

     (2)模型:manufacturer/models.py

    from django.db import models
    
    #制造厂表(一)
    class Manufacturer(models.Model):
        vendor_name = models.CharField("厂商名称", max_length=32, db_index=True, unique=True, help_text="厂商名称")
        tel = models.CharField("联系电话", null=True, max_length=15, help_text="联系电话")
        email = models.EmailField("联系邮件", null=True,blank=True,max_length=32, help_text="联系邮件")
        remark = models.CharField("备注", max_length=300,null=True, help_text="备注")
        def __str__(self):
            return self.vendor_name
        class Meta:
            db_table = "resources_manufacturer"
            ordering = ["id"]
    
    #型号表(多)--foreignkey放多中
    class ProductModel(models.Model):
        model_name = models.CharField("型号名称",max_length=20, help_text="型号名称")
        vendor = models.ForeignKey(Manufacturer,verbose_name="所属制造商", help_text="所属制造商",on_delete=models.CASCADE)
        def __str__(self):
            return self.model_name
        class Meta:
            db_table = "resources_productmodel"
            #排序
            ordering = ["id"]

    (python36env) [vagrant@CentOS7 devops]$ python manage.py makemigrations manufacturer

    (python36env) [vagrant@CentOS7 devops]$ python manage.py migrate manufacturer

    (3)序列化manufacturer/serializers.py:---使用的是模型序列化,所以所有字段的格式,数据类型可直接在模型中加

    from rest_framework import serializers
    from .models import Manufacturer, ProductModel
    #ModelSerializer模型序列化和Serializer序列化的区别是:它有Meta选项,且它帮我们实现了create和update方法,不用再写
    class ManufacturerSerializer(serializers.ModelSerializer):
    
        class Meta:
            #指定它模型是哪个
            model = Manufacturer
            #序列化哪些字段
            fields = "__all__"
    
    class ProductModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = ProductModel
            fields = "__all__"

    (4)视图manufacturer/views.py:

    from django.shortcuts import render
    from rest_framework import viewsets
    from .models import Manufacturer, ProductModel
    from .serializers import ManufacturerSerializer,ProductModelSerializer
    
    class ManufacturerViewset(viewsets.ModelViewSet):
        """
        retrieve:返回指定制造商信息
         list:返回指定制造商列表
         update:更新制造商信息
         destroy:删除制造商记录
         create:创建制造商记录
         partial_update:更新部分字段
        """
        #1.指定queryset
        queryset = Manufacturer.objects.all()
        #2.指定序列化类
        serializer_class = ManufacturerSerializer
    
    class ProductModelViewset(viewsets.ModelViewSet):
        """
        retrieve:返回指定制造商信息
         list:返回指定制造商列表
         update:更新制造商信息
         destroy:删除制造商记录
         create:创建制造商记录
         partial_update:更新部分字段
        """
        #1.指定queryset
        queryset = ProductModel.objects.all()
        #2.指定序列化类
        serializer_class = ProductModelSerializer

    (5)urls.py路由:

    from django.conf.urls import include, url
    from django.contrib import admin
    from rest_framework.routers import DefaultRouter
    from idcs.views import IdcViewset
    from users.views import UserViewset
    from cabinet.views import CabinetViewset
    from manufacturer.views import ManufacturerViewset,ProductModelViewset
    from rest_framework.documentation import include_docs_urls
    
    route = DefaultRouter()
    route.register("idcs", IdcViewset, basename="idcs")
    #注册时三个参数:资源定位符,类,别名
    route.register("users", UserViewset, basename="users")
    route.register("cabinet", CabinetViewset, basename="cabinet")
    route.register("manufacturer", ManufacturerViewset, basename="manufacturer")
    route.register("productmodel", ProductModelViewset, basename="productmodel")
    urlpatterns = [
        url(r'^', include(route.urls)),
        url(r'^docs/', include_docs_urls("lizhihua运维平台接口文档"))
    ]

    效果如下几图

     但是如下图中:

     2.完善功能

    (1)manufacturer/Serializer.py中class ProductModelSerializer类中可增加如下方法:

        def to_representation(self, instance):
            vendor = instance.vendor
            ret = super(ProductModelSerializer, self).to_representation(instance)
            ret["vendor"] = {
                "id": vendor.id,
                "name": vendor.vendor_name
            }
            return ret

    最终效果如下图了:

    但是上述效果中,你若再添加一戴尔的R710型号那模型中是可允许R710有重复的记录,但从业务逻辑上是不允许的, 所以此时就需要通过验证来解决这个问题----从业务层面上去处理这种验证关系--序列化中处理。

    首先这里需要验证的是模型名称不能重复,只要它是个字符串在模型层面是可以重复的,但在业务层面不允许重复---两种方式:基于字段和基于模型去验证

    https://www.django-rest-framework.org/api-guide/validators/#advanced-field-defaults----帮助文档

    (2)manufacturer/Serializer.py中class ProductModelSerializer类中可增加如下方法:

    class ProductModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = ProductModel
            fields = "__all__"
        # #基于字段级别验证法:如把model_name字段转成大写--这只能是单个字段的,若要多个字段要用模型对象级别验证--表级别验证
        # def validate_model_name(self, value):
        #     return value.upper()
        #基于模型对象级别验证法:
        def validate(self, attrs):
            #取到数据
            manufacturer_obj = attrs["vendor"]
            try:
                manufacturer_obj.productmodel_set.get(model_name__exact=attrs["model_name"])
                raise serializers.ValidationError("该型号已经存在")
            except ProductModel.DoesNotExist:
                return attrs
    
        def to_representation(self, instance):
            vendor = instance.vendor
            ret = super(ProductModelSerializer, self).to_representation(instance)
            ret["vendor"] = {
                "id": vendor.id,
                "name": vendor.vendor_name
            }
            return ret
  • 相关阅读:
    9.5 dubbo事件通知机制
    9.4 dubbo异步调用原理
    13.1 dubbo服务降级源码解析
    第十八章 dubbo-monitor计数监控
    12.4 客户端响应解码
    12.3 服务端响应编码
    12.2 服务端请求解码
    12.1 客户端请求编码
    git生成并添加SSH key
    Java并发之原子操作类汇总
  • 原文地址:https://www.cnblogs.com/dbslinux/p/13097363.html
Copyright © 2020-2023  润新知