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

相关文章
|
26天前
|
存储 缓存 前端开发
Django 后端架构开发:存储层调优策略解析
Django 后端架构开发:存储层调优策略解析
36 2
|
22天前
|
JavaScript 前端开发 开发者
哇塞!Vue.js 与 Web Components 携手,掀起前端组件复用风暴,震撼你的开发世界!
【8月更文挑战第30天】这段内容介绍了Vue.js和Web Components在前端开发中的优势及二者结合的可能性。Vue.js提供高效简洁的组件化开发,单个组件包含模板、脚本和样式,方便构建复杂用户界面。Web Components作为新兴技术标准,利用自定义元素、Shadow DOM等技术创建封装性强的自定义HTML元素,实现跨框架复用。结合二者,不仅增强了Web Components的逻辑和交互功能,还实现了Vue.js组件在不同框架中的复用,提高了开发效率和可维护性。未来前端开发中,这种结合将大有可为。
65 0
|
26天前
|
存储 安全 数据安全/隐私保护
Django 后端架构开发:富文本编辑器权限管理与 UEditor 、Wiki接入,实现 Markdown 文本编辑器
Django 后端架构开发:富文本编辑器权限管理与 UEditor 、Wiki接入,实现 Markdown 文本编辑器
63 0
|
26天前
|
负载均衡 应用服务中间件 网络安全
Django后端架构开发:Nginx服务优化实践
Django后端架构开发:Nginx服务优化实践
36 2
|
26天前
|
消息中间件 存储 监控
Django后端架构开发:Celery异步调优,任务队列和调度
Django后端架构开发:Celery异步调优,任务队列和调度
40 1
|
21天前
|
C++ Python
Django视图函数VS类视图:如何选择最适合你的开发方式?
【8月更文挑战第31天】本文对比了Django中的函数视图和类视图。函数视图直接处理HTTP请求和响应,灵活且易于维护,适用于简单业务逻辑;类视图基于Python类,提供更丰富的功能和更高的灵活性,适合处理复杂业务逻辑。选择哪种视图取决于具体需求,合理使用两者可帮助你构建高效且易维护的Django应用。
12 0
|
22天前
|
JavaScript 开发者 UED
Vue.js 错误处理与调试:跟上技术潮流,摆脱开发困扰,成为代码大神不是梦!
【8月更文挑战第30天】在 Vue.js 开发中,错误处理与调试至关重要。本文将对比 Vue 的全局错误捕获机制 `Vue.config.errorHandler` 和组件内 `watch` 监听数据变化的方式,并介绍 Vue 开发者工具、控制台打印 (`console.log`) 以及代码断点 (`debugger`) 等调试方法。此外,还将探讨如何通过自定义错误页面提升用户体验。通过这些技巧的对比,帮助开发者灵活选择适合的策略,确保应用稳定性和开发效率。
39 0
|
22天前
|
JavaScript 前端开发 API
全栈开发革命来临!Vue.js与Node.js联手,打造前后端无缝对接的奇迹之作!
【8月更文挑战第30天】在Web开发领域,前后端分离与协作至关重要。Vue.js以其轻量级和易用性深受前端开发者喜爱,而Node.js则以高性能和事件驱动特性在后端领域崭露头角。二者结合开启了全栈开发新篇章,通过RESTful API或GraphQL实现高效稳定通信。本文以示例说明如何使用Vue.js和Node.js构建全栈应用,从前端Vue组件到后端Express服务器,展示了数据获取与展示的全过程。这种组合提供了一种高效简洁的全栈开发方案,使开发者能更专注于业务逻辑实现。
45 0
|
22天前
|
JavaScript 前端开发 UED
揭秘Vue.js高效开发:Vue Router如何让单页面应用路由管理变得如此简单?
【8月更文挑战第30天】随着Web应用复杂性的增加,单页面应用(SPA)因出色的用户体验和高效的页面加载性能而备受青睐。Vue.js凭借简洁的语法和灵活的组件系统成为构建SPA的热门选择,其官方路由管理器Vue Router则简化了路由管理。本文通过实战示例介绍如何利用Vue Router实现高效的SPA路由管理,包括命名路由、动态路由及其核心优势。
12 0
|
22天前
|
存储 JavaScript 前端开发
【Vue.js的神秘力量】一键解锁:如何让Bootstrap和Vuex成为你的开发超能力?
【8月更文挑战第30天】Vue.js是一个轻量且灵活的JavaScript框架,易于上手且功能强大。为提高开发效率和应用交互性,常需集成第三方库。本文介绍如何在Vue.js项目中集成Bootstrap和Vuex,及其它常见第三方库。Bootstrap提供响应式设计和预制组件,通过安装插件和引入CSS/JS即可集成;Vuex作为官方状态管理库,通过安装并创建store来管理组件状态。此外,Vue.js还可轻松集成Axios和Vue Router等库,提升HTTP请求和页面路由功能。合理选择和集成第三方库能显著提升开发效率,但需保持代码可维护性和可读性。
16 0