vue+django restful framework 电商项目(五) -- 商品类别数据展示

六、商品类别数据展示

6.1. 商品类别数据接口

(1)商品分类有两个接口:

一种是全部分类:一级二级三级

一种是某一类的分类以及商品详细信息:

开始写商品分类的接口

(2)提取第一类

因为有三类的种类, 我们先提取第一类的种类.

view.py代码

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters

from .models import Goods, GoodsCategory
from rest_framework import viewsets
from .serializers import GoodsSerializer, CategorySerializer
from .filter import GoodsFilter

from rest_framework.pagination import PageNumberPagination
from rest_framework import generics


class StandardResultsSetPagination(PageNumberPagination):
    '''
        商品列表自定义分页
    '''
    # 默认每页显示的个数
    page_size = 10
    # 可以动态改变每页显示的个数
    page_size_query_param = 'page_size'
    # 页码参数
    page_query_param = 'p'
    # 最多能显示多少页
    max_page_size = 100


class GoodsListViewSet(viewsets.ModelViewSet):
    """
    商品列表页
    """
    queryset = Goods.objects.all().order_by('-add_time')    # 取出所有对象
    serializer_class = GoodsSerializer                      # 序列化相应的对象
    pagination_class = StandardResultsSetPagination         # 设置分页参数

    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)# 后台过滤设置
    filter_class = GoodsFilter                              # 要过滤的类和字段设置
    search_fields = ('=name', 'goods_brief')                # 搜索的字段
    ordering_fields = ('sold_num', 'add_time')              # 排序功能


class CategoryViewSet(viewsets.ModelViewSet):
    """
        list:
            商品分类列表数据
    """
    queryset = GoodsCategory.objects.filter(category_type=1)    # 取出所有对象
    serializer_class = CategorySerializer                       # 序列化相应的对象

  """
        list:
            商品分类列表数据
    """  

  这一块这么写的原因是后面以便于生产api文档.

  urls.py

"""VueShopProject URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.1/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.conf.urls import url,include
from django.views.static import serve

import xadmin
from VueShopProject.settings import MEDIA_ROOT
from rest_framework import routers

from goods import views

router = routers.DefaultRouter()                    # 注册默认的路由类
router.register(r'goods', views.GoodsListViewSet)   # 添加goods路由信息到路由类
router.register(r'categorys', views.CategoryViewSet)# 添加category路由信息


urlpatterns = [
    url('xadmin/', xadmin.site.urls),                   # xadmin后台url
    url(r'^ueditor/', include('DjangoUeditor.urls')),   # 富文本编辑器url
    url(r'media/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT}),# mediaurl

    url(r'^api-auth/', include('rest_framework.urls')),                 # drf 路由
    url(r'^', include(router.urls)),                                    # drf的路由表
]

运行代码后, 我们看看返回结果.

和我们预期一样, 成功提取, 我们再想想怎么提取第二类类别

(2)提取第二类

怎么来提取第二类呢? 我们先想想第二类和第一类有什么联系吧, 第二类和第一类的联系取决于第二类中定义了一个parent_category字段, 该字段指向上一级, 而该字段有一个属性叫 related_name="sub_cat"

related_name的作用是用于处理外键之间的联系的, 详情见:https://blog.csdn.net/wuliangtianzu/article/details/82656647

在这我们可以通过sub_cat字段来看看有哪些二级类是一级类的, 我们把序列化类做一下修改:serializers.py

from .models import Goods, GoodsCategory
from rest_framework import serializers


class CategorySerializer2(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = "__all__"


class CategorySerializer(serializers.ModelSerializer):
    """
    商品类别序列化
    """
    sub_cat = CategorySerializer2(many=True)

    class Meta:
        model = GoodsCategory   # 序列化的module
        fields = "__all__"      # 序列化的字段


class GoodsSerializer(serializers.ModelSerializer):
    """
    商品序列化
    """
    category = CategorySerializer()     # 实例化对象的名字一定要和外键字段的名字一样

    class Meta:
        model = Goods       # 要序列化的类
        fields = "__all__"  # 要序列化的字段

我们在原来的基础上增加了 CategorySerializer2 类, 和对 CategorySerializer 做了修改

注意: sub_cat = CategorySerializer2(many=True)这一句一定要加many=true, 不然会报如下的错,

我们运行一下功能, 看能不能运行, 访问: http://127.0.0.1:8000/categorys/

得到如下的数据:

返回成功

(3)提取第三类

既然第二类都可以提取了, 而且思路一样, 第三类我就直接贴代码了,   serializers.py

from .models import Goods, GoodsCategory
from rest_framework import serializers


class CategorySerializer3(serializers.ModelSerializer):
    """
        商品类别3序列化
    """
    class Meta:
        model = GoodsCategory
        fields = "__all__"


class CategorySerializer2(serializers.ModelSerializer):
    """
        商品类别2序列化
    """
    sub_cat = CategorySerializer3(many=True)    # 取类别2下类别3的对象

    class Meta:
        model = GoodsCategory()
        fields = "__all__"


class CategorySerializer(serializers.ModelSerializer):
    """
    商品类别1序列化
    """
    sub_cat = CategorySerializer2(many=True)    # 取类别1下类别2的对象

    class Meta:
        model = GoodsCategory   # 序列化的module
        fields = "__all__"      # 序列化的字段


class GoodsSerializer(serializers.ModelSerializer):
    """
    商品序列化
    """
    category = CategorySerializer()     # 实例化对象的名字一定要和外键字段的名字一样

    class Meta:
        model = Goods       # 要序列化的类
        fields = "__all__"  # 要序列化的字段

(4)提取任意第一类别

我们都把全部数据都提取出来了, 但是我们不是要全部类别的数据, 而是只是要一类的数据, 那应该怎么提取, 这个问题呢?  drf已经帮我们考虑好了, 在url后面加上相应的id就可以访问对应的类了, 比如, 我想访问id=1的第一类类别, 只需访问:http://127.0.0.1:8000/categorys/1/   就可以了

如下图所示:

6.2.vue展示商品分类数据 

        我们来看看怎么展示数据吧, 关于vue的知识我不做解释, 因为vue涉及一大块内容, 解释起来很要时间, 而且我主要是做后端开发, 前端不想深入了解, 来看看怎么展示数据吧.

        首先我们得打开vue的源码目录, 如图:

       

       如图打开online-store->src->api->api.js api.js这里存放这整个项目的api设置, 首先我们的改一下如上图所示的host地址, 改为本地的地址和本地的端口, 视频中老师说另起一个变量, 这样做最好了, 因为老师原来的后台已经不能用了, 所以我就索性改为自己的本地地址.

       然后运行vue工程, 在onlin-store目录下运行npm run dev 命令, 看看效果:

     

    没有一点效果, 怎么回事, 这是因为涉及到跨域问题, 因为我们后台端口是8000, 而前端是8080 已经跨域了,  解决跨域问题, 前端后台后可以做, 我现在讲讲后台怎么解决跨域问题.

drf跨域问题

后端服务器解决跨域问题的方法:

(1)安装模块

pip install django-cors-headers
django-cors-headers 使用说明:https://github.com/ottoyiu/django-cors-headers

(2)添加到INSTALL_APPS中

INSTALLED_APPS = (
    ...
      'corsheaders',
 ... )

(3)添加中间件

下面添加中间件的说明:

CorsMiddleware should be placed as high as possible, especially before any middleware that can generate responses such as Django's CommonMiddleware or Whitenoise's WhiteNoiseMiddleware. If it is not before, it will not be able to add the CORS headers to these responses.

Also if you are using CORS_REPLACE_HTTPS_REFERER it should be placed before Django's CsrfViewMiddleware (see more below).

意思就是 要放的尽可能靠前,必须在CsrfViewMiddleware之前。我们直接放在第一个位置就好了

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

(4)设置为True(在setting下)

CORS_ORIGIN_ALLOW_ALL = True

现在再访问 http://127.0.0.1:8080/#/app/home/index   数据就可以填充进来了

在一级分类中设置为True

 

6.3.vue展示商品列表页数据 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零涂

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值