Django+Vue开发生鲜电商平台之5.使用DRF实现商品列表页和过滤(上)

简介: 先了解Django中实现Json数据传递的基本方法,可以查看中文文档

一、普通方式实现商品列表页

先了解Django中实现Json数据传递的基本方法,可以查看中文文档https://www.cntofu.com/book/35/index.html,并结合英文文档了解其用法。

1.使用Django View实现商品列表

下面实现通过View类直接将商品信息显示到前端。

为了区别于views.py,在apps/goods下新建views_base.py如下:

import json
from django.views.generic.base import View
from django.http import HttpResponse
from goods.models import Goods
class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, bytes):
            return str(obj, encoding='utf-8')
        return json.JSONEncoder.default(self, obj)
class GoodsListView(View):
    def get(self, request):
        '''通过View实现商品列表页'''
        json_list = []
        goods = Goods.objects.all()[:10]
        for good in goods:
            json_dict = {}
            json_dict["name"] = good.name
            json_dict["category"] = good.category.name
            json_dict["market_price"] = good.market_price
            json_list.append(json_dict)
        return HttpResponse(json.dumps(json_list, ensure_ascii=False), content_type='application/json')

urls.py中加入路由如下:

urlpatterns = [
       url(r'^xadmin/', xadmin.site.urls),
       url(r'^media/(?P<path>.*)$', serve, {'document_root':MEDIA_ROOT}),
       # 商品列表页
       url(r'goods/$', GoodsListView.as_view(), name='goods-list')
]

显示:

2345_image_file_copy_2.jpg

显然,数据以json的形式返回前端。

但是从代码中可以看到:

通过在新建列表、其元素为单个商品信息组成的字典,一个一个地添加,显得很麻烦,可进行改进;

有些字段不能直接用json.dumps()方法序列化,如datetime,会报错,如商品列表视图修改为如下时:

class GoodsListView(View):
    def get(self, request):
        '''通过View实现商品列表页'''
        json_list = []
        goods = Goods.objects.all()[:10]
        for good in goods:
            json_dict = {}
            json_dict["name"] = good.name
            json_dict["category"] = good.category.name
            json_dict["market_price"] = good.market_price
            json_dict["add_time"] = good.add_time
            json_list.append(json_dict)
        return HttpResponse(json.dumps(json_list, ensure_ascii=False))

会报错:

raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type date is not JSON serializable

显然可以进行改进。

2.serializer序列化model

使用Django自带的model_to_dict()方法可以实现直接将模型数据转化为字典形式,但是对于DateTimeField、ImageField等字段时还是无法序列化,因此需要使用serializer进行序列化,views_base.py如下:

import json
from django.views.generic.base import View
from django.http import HttpResponse, JsonResponse
from django.forms.models import model_to_dict
from django.core import serializers
from goods.models import Goods
class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, bytes):
            return str(obj, encoding='utf-8')
        return json.JSONEncoder.default(self, obj)
class GoodsListView(View):
    def get(self, request):
        '''通过serializers实现商品列表页'''
        goods = Goods.objects.all()[:10]
        json_data = serializers.serialize('json', goods)
        json_data = json.loads(json_data)
        return HttpResponse(json.dumps(json_data), content_type='application/json')

显示:

image.jpeg

显然,此时所有字段都可以显示到前端,还可以简化如下:

class GoodsListView(View):
    def get(self, request):
        '''通过serializers实现商品列表页'''
        goods = Goods.objects.all()[:10]
        json_data = serializers.serialize('json', goods)
        return HttpResponse(json_data, content_type='application/json')

还可以直接使用JsonResponse对象,如下:

class GoodsListView(View):
    def get(self, request):
        '''通过serializers实现商品列表页'''
        goods = Goods.objects.all()[:10]
        json_data = serializers.serialize('json', goods)
        return JsonResponse(json.loads(json_data), safe=False)

效果与之前一样。

虽然Django已经可以实现Json数据传递,但是我们还是采用Restful framework,因为其对Django自带功能实现了进一步优化,更方便使用。

二、DRF实现商品列表页

Django Restful framework简称DRF,可以查看官方文档https://www.django-rest-framework.org/,从官方文档可以看到,Django REST框架是用于构建Web API的功能强大且灵活的工具包。

使用REST框架的一些原因:

该网站可浏览API是你的开发人员一个巨大的可用性胜利;

身份验证策略,包括OAuth1a和OAuth2的软件包;

支持ORM和非ORM数据源的序列化;

完全可自定义;

广泛的文档资料以及强大的社区支持。

要使用DRF,还需要DRF所依赖的第三方库django-guardian、coreapi,直接通过命令添加即可,还需要在settings.py中进行配置:

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'apps.users.apps.UsersConfig',
    'goods.apps.GoodsConfig',
    'trade.apps.TradeConfig',
    'user_operation.apps.UserOperationConfig',
    'DjangoUeditor',
    'xadmin',
    'crispy_forms',
    'django.contrib.admin',
    'rest_framework',
]

1.使用serializer实现基本序列化

通过DRF实现商品列表页的原理是:

通过DRF返回数据,基于CBV(Class-based Views, 即基于类的视图)方式编码。

urls.py中配置路径:

from django.conf.urls import url, include
from django.views.static import serve
from rest_framework.documentation import include_docs_urls
import xadmin
from .settings import MEDIA_ROOT
from goods.views_base import GoodsListView
urlpatterns = [
       url(r'^xadmin/', xadmin.site.urls),
       url(r'^media/(?P<path>.*)$', serve, {'document_root':MEDIA_ROOT}),
       url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
       # 商品列表页
       url(r'goods/$', GoodsListView.as_view(), name='goods-list'),
       # 文档路由
       url(r'docs/', include_docs_urls(title='生鲜电商'))
]

apps/goods下新建serializers.py如下:

from rest_framework import serializers
class GoodsSerializer(serializers.Serializer):
    name = serializers.CharField(required=True, max_length=300)
    click_num = serializers.IntegerField(default=0)

现在建立基于类的视图CBV,apps/goods/views.py如下:

from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Goods
from .serializers import GoodsSerializer
# Create your views here.
class GoodsListView(APIView):
    '''商品序列化'''
    def get(self, request, format=None):
        goods = Goods.objects.all()[:10]
        goods_serializer = GoodsSerializer(goods, many=True)
        return Response(goods_serializer.data)

urls.py修改如下:

from django.conf.urls import url, include
from django.views.static import serve
from rest_framework.documentation import include_docs_urls
import xadmin
from .settings import MEDIA_ROOT
from goods.views import GoodsListView
urlpatterns = [
       url(r'^xadmin/', xadmin.site.urls),
       url(r'^media/(?P<path>.*)$', serve, {'document_root':MEDIA_ROOT}),
       url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
       # 商品列表页
       url(r'goods/$', GoodsListView.as_view(), name='goods-list'),
       # 文档路由
       url(r'docs/', include_docs_urls(title='生鲜电商'))
]

此时再访问http://127.0.0.1:8000/goods/,显示:

2345_image_file_copy_4.jpg

显然,此时还是显示出了数据,并且经过restful_framework优化,不是单纯地显示json数据,而且可以通过json和API两种方式查看,还能查看OPTIONS数据。

如果报错__str__ returned non-string (type NoneType),可以通过退出登录后台管理或者修改自定义的用户模型的__str__()方法解决,具体可参考https://blog.csdn.net/CUFEECR/article/details/107469168

相关文章
|
4天前
|
存储 前端开发 关系型数据库
108-Django开发在线书店
该项目是一个使用Python Django框架开发的在线书店系统,提供用户管理(包括普通用户、管理员和匿名用户)、权限管理、书籍管理、订单管理和额外功能(搜索、购物车、支付和评论)。系统支持安全的HTTPS传输和加密密码存储,保证用户数据安全。通过Django实现了用户购书、管理员后台管理的全面功能,兼顾易用性和可维护性。
13 0
|
6天前
|
缓存 数据挖掘 数据库
104-Django开发在线美食购物网站
美味小厨在线购物网站是基于Python和Django构建的电商平台,提供商品展示、搜索过滤、问题反馈、购物功能、商品详情查看、产品编辑添加、多用户及站点管理、订单管理等服务。采用Django框架实现高效、稳定且可扩展的系统,前后端分离以提升性能,支持数据库优化和缓存技术,注重用户数据安全。未来计划优化用户体验,拓展更多功能,并加强数据分析。
11 1
|
2天前
|
前端开发 JavaScript 数据库
110-Django开发社交聊天网站
该内容描述了一个聊天网站的功能模块和技术实现要点,主要包括: 1. 用户管理:用户注册、登录/登出、信息编辑和密码管理。 2. 权限管理:角色定义、权限分配和访问控制。 3. 好友管理:添加、查看、删除好友及处理好友请求。 4. 通讯管理:创建聊天室、在线聊天、消息发送/接收、历史记录和实时通知。 5. 技术实现:使用Django认证系统、channels库支持WebSocket、MySQL数据库、前端技术(如HTML/CSS/JavaScript)以及性能优化。 请注意,由于字符限制,部分图片无法在摘要中展示。
19 6
|
2天前
|
监控 安全 NoSQL
采用java+springboot+vue.js+uniapp开发的一整套云MES系统源码 MES制造管理系统源码
MES系统是一套具备实时管理能力,建立一个全面的、集成的、稳定的制造物流质量控制体系;对生产线、工艺、人员、品质、效率等多方位的监控、分析、改进,满足精细化、透明化、自动化、实时化、数据化、一体化管理,实现企业柔性化制造管理。
23 3
|
3天前
|
前端开发 关系型数据库 MySQL
109-Django开发考试与问卷系统
该项目描述了用户、测试和权限三个核心模块的详细需求。用户模块包括注册(需验证信息并唯一性检查,密码安全存储,确认邮件)和登录(凭据验证,可选的“记住我”功能,防止暴力破解)。测试模块涉及题目、选项和分数设置,支持创建、编辑及自动评分。权限模块关注用户角色和权限管理,实现访问控制。其他考虑因素涵盖用户界面、数据库选择(如SQLite3和MySQL)、安全性最佳实践以及系统的可维护性和可扩展性。
14 3
|
5天前
|
前端开发 JavaScript 测试技术
107-Django开发医院管理系统(医生-患者-医院管理员)
该内容描述了一个基于Python和Django的医疗管理系统的开发步骤。主要涵盖以下关键点: 1. 环境搭建:安装Python和Django,创建项目和应用。 2. 数据库模型:设计用户、医生、患者、发票和预约等模型。 3. 用户认证和权限:使用Django内置系统,创建自定义角色和权限。 4. 视图和模板:处理用户请求,渲染HTML页面,包括医生列表、患者注册、管理界面等。 5. 表单处理:创建表单处理用户输入,验证数据并保存到数据库。 6. PDF生成:利用xhtml2pdf库生成治疗发票的PDF。 7. 路由配置:设置URL路由以连接视图。
19 7
107-Django开发医院管理系统(医生-患者-医院管理员)
|
6天前
|
数据库 数据安全/隐私保护 开发者
106-Django开发在线交易网站
该内容是关于使用Django框架开发电子商务网站的步骤摘要:
16 2
|
6天前
|
存储 前端开发 关系型数据库
105-Django开发多商户询盘上级网站-在线聊天交流通讯
该项目旨在构建一个在线询盘交易系统,采用Python的Django框架,支持SQLite3(开发)或MySQL/PostgreSQL(生产)数据库。功能包括用户注册登录、产品上传(带审核)、搜索过滤、即时通讯、超级用户管理端、数据分析和响应式界面。还将考虑使用WebSocket、Redis缓存、Docker部署和推荐算法。数据库设计涉及用户、产品、订单和聊天记录表。开发流程涵盖需求分析、技术选型、数据库设计、编码、测试和部署,同时关注安全性、性能、可维护性和兼容性。
13 2
|
6天前
|
前端开发 UED Python
Wagtail-基于Python Django的内容管理系统CMS实现公网访问
Wagtail-基于Python Django的内容管理系统CMS实现公网访问