京西商城——商品相关接口开发

文章目录

  • 接口开发
    • django原生CBV开发==商品分类菜单==接口
    • 继承APIView开发==商品类型分类==接口
    • 通过序列化器开发==商品详情==接口

接口开发

django原生CBV开发商品分类菜单接口

先直接给出最终的views类,先简单的解释一下:

在基于CBV(基于类视图的)的接口时,直接在类中定义名字于请求名相等的方法即可

get请求中需要先获取符合条件的数据库中的数据

result_json = {‘status’: 1000, ‘data’: []} 是先定义一个返回的格式,‘status’: 1000是这个接口的响应码,通过循环将数据库中的数据会放在data中

最后返回一个HttpResponse响应,一定要清楚接口最后返回的是JSON数据,所以在返回Http响应响应时一定要用json.dumps函数将数据转化成JSON。

在代码中的for循环中,我一共打印了三组数据,反别是item,item.to_dict,result_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_type='application/json')# json.drup()将字典转化为JSON,content_type='application/json'告诉客户端这个响应是JSON格式的数据,客户端应该相应地处理它。class SubMenuView(View):def get(self, request):# 获取请求的参数param_id = request.GET['main_menu_id']sub_menu = SubMenu.objects.filter(main_menu_id=param_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_length=255, verbose_name='菜单名称', null=False)main_menu_url = models.CharField(max_length=255, null=True, blank=True, 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_menu'class SubMenu(models.Model):main_menu_id = models.IntegerField( null=True, blank=True, verbose_name='一级菜单ID')submenu_id = models.IntegerField( null=True, blank=True, verbose_name='二级菜单ID')submenu_name = models.CharField(max_length=255, verbose_name='二级菜单名称', null=False)submenu_type = models.CharField(max_length=255, null=True, blank=True, verbose_name='二级菜单类型')submenu_url = models.CharField(max_length=255, null=True, blank=True, 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_type='application/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_type='application/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_type='application/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_id=category_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, cls=DecimalEncoder), content_type='application/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, cls=DecimalEncoder), content_type='application/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, cls=DecimalEncoder), content_type='application/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_id=sku_id)return ResponseMessage.GoodsResponse.success(good)

因为商品详情是根据商品属性中的sku_id查找的,再此前的数据库设计的时候我没有添加这个属性,所以现在要添加这个属性

    sku_id = models.IntegerField(unique=True,null=False, verbose_name="sku_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_id=sku_id)  # 返回的是一个QuerySet查询集,并不是一个对象,哪怕符合条件的只有一个对象。good_data = Goods.objects.filter(sku_id=sku_id).first()  # 获取 QuerySet 中的第一个模型实例,是一个对象# 序列化的参数是instance,反序列化的参数是dataresult = GoodsSerializer(instance=good_data)result_json = {'status': '2000', 'data': result.data}return HttpResponse(json.dumps(result_json), content_type='application/json')

此时我们就可以通过sku_id来获取JSON格式的数据了:

在这里插入图片描述

特殊处理的字段会在最前面。
在上面我们用first()函数拿到了QuerySet查询集中的第一个实例,实际上还有另一种写法

  def get(self, request, sku_id):good_data = Goods.objects.filter(sku_id=sku_id)print(type(good_data))# 设置 many=True 表示告诉序列化器要处理多个对象也就是传入的instance是一个包含多个对象的查询集,通常用于处理查询集(QuerySet)返回的结果result = GoodsSerializer(instance=good_data, many=True)result_json = {'status': '2000', 'data': result.data}return HttpResponse(json.dumps(result_json), content_type='application/json')

直接用many=True告诉序列化器你要处理一个包含多个对象的查询集,他就会自己遍历并序列化了。


如果不特殊处理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_id=sku_id)result = GoodsSerializer(instance=good_data)result_json = {'status': '2000', 'data': result.data}return HttpResponse(json.dumps(result_json), content_type='application/json')

在这里插入图片描述

若有错误与不足请指出,关注DPT一起进步吧!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/573182.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Chrome之解决:插件不能使用问题(十三)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

软件部署资源计算工具:精确评估资源需求

软件部署资源计算工具:精确评估资源需求 在当今快速发展的信息技术时代,软件部署已成为企业运营不可或缺的一部分。然而,一个常见的挑战是如何精确评估软件部署所需的资源。资源评估不仅关系到软件的性能和稳定性,还直接影响到成…

解决kubesphere流水线docker登陆错误http: server gave HTTP response to HTTPS client

kubesphere DevOps流水线中,在登录私有的harbor仓库时,报以下错误 docker login 111.230.19.120:80 -u admin -p test123. WARNING! Using --password via the CLI is insecure. Use --password-stdin. Error response from daemon: Get "https://…

4S店车辆管理系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW,文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文(设计)学生选题参考合集推荐收藏(包含Springboot、jsp、ssmvue等技术项目合集) 目录 1. 管…

neo4j相同查询语句一次查询特慢再次查询比较快。

现象&#xff1a; neo4j相同查询语句一次查询特慢再次查询比较快。 分析&#xff1a; 查询语句 //查询同名方法match(path:Method) where id(path) in [244333030] and NOT path:Constructor//是rpc的方法match(rpc_method:Method)<-[:DECLARES]-(rpc_method_cls:Class) -…

文生图大模型Stable Diffusion的前世今生!

1、引言 跨模态大模型是指能够在不同感官模态(如视觉、语言、音频等)之间进行信息转换的大规模语言模型。当前图文跨模态大模型主要有&#xff1a; 文生图大模型&#xff1a;如 Stable Diffusion系列、DALL-E系列、Imagen等 图文匹配大模型&#xff1a;如CLIP、Chinese CLIP、…

【前端】layui学习笔记

参考视频&#xff1a;LayUI 1.介绍 官网&#xff1a;http://layui.apixx.net/index.html 国人16年开发的框架,拿来即用,门槛低 … 2. LayUi的安装及使用 Layui 是一套开源的 Web UI 组件库&#xff0c;采用自身轻量级模块化规范&#xff0c;遵循原生态的 HTML/CSS/JavaScript…

论文阅读,Accelerating the Lattice Boltzmann Method(五)

目录 一、Article:文献出处&#xff08;方便再次搜索&#xff09; &#xff08;1&#xff09;作者 &#xff08;2&#xff09;文献题目 &#xff08;3&#xff09;文献时间 &#xff08;4&#xff09;引用 二、Data:文献数据&#xff08;总结归纳&#xff0c;方便理解&am…

【spring】@Value注解学习

Value介绍 Value 是 Spring 框架中一个非常有用的注解&#xff0c;它允许你将来自配置文件、系统属性、环境变量或者通过 SpEL&#xff08;Spring Expression Language&#xff09;表达式计算得出的值注入到 Spring 管理的 Bean 中。这个注解可以用在字段、setter 方法或者构造…

数据结构初阶:排序

排序的概念及其运用 排序的概念 排序 &#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性 &#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&…

如何在家中使用手机平板电脑 公司iStoreOS软路由实现远程桌面

文章目录 简介一、配置远程桌面公网地址二、家中使用永久固定地址 访问公司电脑**具体操作方法是&#xff1a;** 简介 软路由是PC的硬件加上路由系统来实现路由器的功能&#xff0c;也可以说是使用软件达成路由功能的路由器。 使用软路由控制局域网内计算机的好处&#xff1a…

【漏洞复现】网络验证系统getInfo接口处存在SQL注入漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…