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