浙江网站建设公司推荐,wordpress 3清新主题,上海建网站服务器,做教育培训网站文章目录 接口开发django原生CBV开发商品分类菜单接口继承APIView开发商品类型分类接口通过序列化器开发商品详情接口 接口开发
django原生CBV开发商品分类菜单接口
先直接给出最终的views类#xff0c;先简单的解释一下#xff1a;
在基于CBV#xff08;基于类视图的商品分类菜单接口继承APIView开发商品类型分类接口通过序列化器开发商品详情接口 接口开发
django原生CBV开发商品分类菜单接口
先直接给出最终的views类先简单的解释一下
在基于CBV基于类视图的的接口时直接在类中定义名字于请求名相等的方法即可
get请求中需要先获取符合条件的数据库中的数据
result_json {‘status’: 1000, ‘data’: []} 是先定义一个返回的格式‘status’: 1000是这个接口的响应码通过循环将数据库中的数据会放在data中
最后返回一个HttpResponse响应一定要清楚接口最后返回的是JSON数据所以在返回Http响应响应时一定要用json.dumps函数将数据转化成JSON。 在代码中的for循环中我一共打印了三组数据反别是itemitem.to_dictresult_json。他们的类型分别是对象字典字典。那么to_dict函数的意义又是什么呢因为json.dumps函数不可以直接将自定义对象转换为JSON数据所以需要在每一个model中定义一个方法to_dict方法将对象先转化为字典的形式。再通过json.dumps再返回时转化为JSON。 一级菜单接口和二级菜单接口
menu/views.py
import json
from django.http import HttpResponse
from django.views import View
from apps.menu.models import MainMenu, SubMenu
from utils import ResponseMessageclass MainMenuView(View):def get(self, request):main_menu MainMenu.objects.all()result_json {status: 1000, data: []}for item in main_menu:# print(item) # item是对象 MainMenu object (1) MainMenu object (2) MainMenu object (3) MainMenu object (4)........# print(item.to_dict()) # {main_menu_id: 1, main_menu_name: 家用电器}{main_menu_id: 2, main_menu_name: 手机}{main_menu_id: 2, main_menu_name: 运营商}result_json[data].append(item.to_dict()) #要通过每个item对象里的to_dict方法序列化对象# print(result_json) # 字典并不是JSON格式的数据return HttpResponse(json.dumps(result_json), content_typeapplication/json)# json.drup()将字典转化为JSONcontent_typeapplication/json告诉客户端这个响应是JSON格式的数据客户端应该相应地处理它。class SubMenuView(View):def get(self, request):# 获取请求的参数param_id request.GET[main_menu_id]sub_menu SubMenu.objects.filter(main_menu_idparam_id)# 封装一个同意接受数据返回请求的方法return ResponseMessage.MenuResponse.success(sub_menu)在模型类中添加to_dict方法
menu/models.py
import jsonfrom django.db import modelsclass MainMenu(models.Model):main_menu_id models.IntegerField(verbose_name菜单ID)main_menu_name models.CharField(max_length255, verbose_name菜单名称, nullFalse)main_menu_url models.CharField(max_length255, nullTrue, blankTrue, verbose_name菜单地址)# 手动序列化def to_dict(self):return {main_menu_id: self.main_menu_id,main_menu_name: self.main_menu_name,}class Meta:db_table main_menuclass SubMenu(models.Model):main_menu_id models.IntegerField( nullTrue, blankTrue, verbose_name一级菜单ID)submenu_id models.IntegerField( nullTrue, blankTrue, verbose_name二级菜单ID)submenu_name models.CharField(max_length255, verbose_name二级菜单名称, nullFalse)submenu_type models.CharField(max_length255, nullTrue, blankTrue, verbose_name二级菜单类型)submenu_url models.CharField(max_length255, nullTrue, blankTrue, verbose_name二级菜单地址)def to_dict(self):return{main_menu_id: self.main_menu_id,submenu_id: self.submenu_id,submenu_name: self.submenu_name,submenu_type: self.submenu_type,submenu_url: self.submenu_url,}class Meta:db_table sub_menu因为在写每一个接口时数据返回逻辑就是每一个接口都要序列化然后转化为JSON所以干脆创建一个工具类用来让每一个接口直接调用这个工具类。
utils/ResponseMessage.py
from django.http import HttpResponse#分类菜单
class MenuResponse():staticmethoddef success(data):result_json {status: 1000, data: []}for item in data:result_json[data].append(item.to_dict())return HttpResponse(json.dumps(result_json), content_typeapplication/json)staticmethoddef failed(data):result_json {status: 1001, data: []}for item in data:result_json[data].append(item.to_dict())return HttpResponse(json.dumps(result_json), content_typeapplication/json)staticmethoddef other(data):result_json {status: 1002, data: []}for item in data:result_json[data].append(item.to_dict())return HttpResponse(json.dumps(result_json), content_typeapplication/json)继承APIView开发商品类型分类接口
这个接口中基于APIView的接口开发和基于View的开发没有任何区别因为在面向对象中APIView本身就是继承于View的所以继承APIView会先在APIView找如果APIView没有封装该方法那么才会执行View中的方法
from rest_framework.views import APIView
from apps.goods.models import Goods
from utils import ResponseMessage# http://localhost:8000/goods/category_id/page
class GoodsCategoryAPIView(APIView):def get(self, request, category_id, page):current_page (page - 1) * 20 #当前页的起始位置end_page page * 20 #当前页的结束位置category_data Goods.objects.filter(type_idcategory_id)[current_page:end_page]return ResponseMessage.GoodsResponse.success(category_data)这个时候要在ResponseMessage.py中加入商品分类的工具类当然不能忘记在goods/models类中加入to_dict进行手动系列化
import decimal
import json
from django.http import HttpResponse# 商品分类
class GoodsResponse():staticmethoddef success(data):result_json {status: 2000, data: []}for item in data:result_json[data].append(item.to_dict())return HttpResponse(json.dumps(result_json, clsDecimalEncoder), content_typeapplication/json)staticmethoddef failed(data):result_json {status: 2001, data: []}for item in data:result_json[data].append(item.to_dict())return HttpResponse(json.dumps(result_json, clsDecimalEncoder), content_typeapplication/json)staticmethoddef other(data):result_json {status: 2002, data: []}for item in data:result_json[data].append(item.to_dict())return HttpResponse(json.dumps(result_json, clsDecimalEncoder), content_typeapplication/json)class DecimalEncoder(json.JSONEncoder):def default(self, obj):if isinstance(obj, decimal.Decimal):return float(obj)这个编码器类用于处理 JSON 序列化过程中的Decimal 类型json模块不能处理这种类型。通过指定 cls 参数你可以确保所有的 Decimal 对象都被正确地转换为 JSON 字符串 通过序列化器开发商品详情接口
在使用序列化器之前我们先用手动序列化的方式来实现商品详情接口
goods/views
# http://localhost:8000/goods/sku_id
class GoodsDetailAPIView(APIView):def get(self, request, sku_id):good Goods.objects.filter(sku_idsku_id)return ResponseMessage.GoodsResponse.success(good)因为商品详情是根据商品属性中的sku_id查找的再此前的数据库设计的时候我没有添加这个属性所以现在要添加这个属性 sku_id models.IntegerField(uniqueTrue,nullFalse, verbose_namesku_id)python manage.py makemigrations python manage.py migrate使用序列化器
使用序列化器要现创建一个继承自 serializers.ModelSerializer 的类一般在app下创建一个serializers.py。
# goods/serializers.py
from rest_framework import serializers
from apps.goods.models import Goods
from jingxi_shop_project.settings import IMAGE_URLclass GoodsSerializer(serializers.ModelSerializer):# SerializerMethodField方法允许你为序列化器定义一个名为 get_属性 的方法这个方法返回的值将作为该字段的值在序列化时输出photo_URL serializers.SerializerMethodField()def get_photo_URL(self, obj):return IMAGE_URL obj.photo_URLclass Meta:model Goods # 指定了序列化器将要序列化的模型类是Goodsfields __all__ # 序列化器将包含模型定义的所有字段# goods/views.py
# http://localhost:8000/goods/sku_id
class GoodsDetailAPIView(APIView):def get(self, request, sku_id):# good_data Goods.objects.filter(sku_idsku_id) # 返回的是一个QuerySet查询集并不是一个对象哪怕符合条件的只有一个对象。good_data Goods.objects.filter(sku_idsku_id).first() # 获取 QuerySet 中的第一个模型实例是一个对象# 序列化的参数是instance反序列化的参数是dataresult GoodsSerializer(instancegood_data)result_json {status: 2000, data: result.data}return HttpResponse(json.dumps(result_json), content_typeapplication/json)
此时我们就可以通过sku_id来获取JSON格式的数据了 特殊处理的字段会在最前面。 在上面我们用first()函数拿到了QuerySet查询集中的第一个实例实际上还有另一种写法 def get(self, request, sku_id):good_data Goods.objects.filter(sku_idsku_id)print(type(good_data))# 设置 manyTrue 表示告诉序列化器要处理多个对象也就是传入的instance是一个包含多个对象的查询集通常用于处理查询集QuerySet返回的结果result GoodsSerializer(instancegood_data, manyTrue)result_json {status: 2000, data: result.data}return HttpResponse(json.dumps(result_json), content_typeapplication/json)直接用manyTrue告诉序列化器你要处理一个包含多个对象的查询集他就会自己遍历并序列化了。 如果不特殊处理photo_URL这个字段就会输出数据库中最原始的数据
# goods/serializers.py
from rest_framework import serializers
from apps.goods.models import Goods
from jingxi_shop_project.settings import IMAGE_URLclass GoodsSerializer(serializers.ModelSerializer):class Meta:model Goodsfields __all__# goods/views.py
class GoodsDetailAPIView(APIView):def get(self, request, sku_id):good_data Goods.objects.filter(sku_idsku_id)result GoodsSerializer(instancegood_data)result_json {status: 2000, data: result.data}return HttpResponse(json.dumps(result_json), content_typeapplication/json)若有错误与不足请指出关注DPT一起进步吧