Django REST framework+Vue 打造生鮮超市(五)

目錄html

生鮮超市(一)    生鮮超市(二)    生鮮超市(三)   前端

生鮮超市(四)    生鮮超市(五)    生鮮超市(六)   vue

生鮮超市(七)    生鮮超市(八)    生鮮超市(九)   ios

生鮮超市(十)    生鮮超市(十一)    生鮮超市(十二)    生鮮超市(十三)   git

代碼下載github

githubdjango

教程axios

學習自慕課網-前端vue結合後端DjangoFramework的在線生鮮超市 後端

6、商品類別數據展現

6.1. 商品類別數據接口

(1)商品分類有兩個接口:api

一種是所有分類:一級二級三級

 

 

  一種是某一類的分類以及商品詳細信息:

 

 開始寫商品分類的接口

(2)序列化

給分類添加三級分類的serializer

 goods/serializers.py

from rest_framework import serializers
from .models import Goods,GoodsCategory


class CategorySerializer3(serializers.ModelSerializer):
    '''三級分類'''
    class Meta:
        model = GoodsCategory
        fields = "__all__"


class CategorySerializer2(serializers.ModelSerializer):
    '''
    二級分類
    '''
    #在parent_category字段中定義的related_name="sub_cat" 
    sub_cat = CategorySerializer3(many=True)
    class Meta:
        model = GoodsCategory
        fields = "__all__"


class CategorySerializer(serializers.ModelSerializer):
    """
    商品一級類別序列化
    """
    sub_cat = CategorySerializer2(many=True)
    class Meta:
        model = GoodsCategory
        fields = "__all__"

(3)views.py

class CategoryViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    '''
    list:
        商品分類列表數據
    '''

    queryset = GoodsCategory.objects.filter(category_type=1)
    serializer_class = CategorySerializer

說明:

  • 註釋的內容,在後面生成drf文檔的時候會顯示出來,全部要寫清楚
  • 要想獲取某一個商品的詳情的時候,繼承 mixins.RetrieveModelMixin  就能夠了

 (4)url配置

# 配置Category的url
router.register(r'categorys', CategoryViewSet, base_name="categorys")

 

6.2.vue展現商品分類數據

 接口相關代碼都放在src/api/api.js裏面,調試接口的時候咱們首先須要新建一個本身的host,而後替換要調試的host

(1)新建local_host

let local_host = 'http://127.0.0.1:8000'

(2)替換商品類別默認的host

//獲取商品類別信息
export const getCategory = params => {
  if('id' in params){
    return axios.get(`${local_host}/categorys/`+params.id+'/');
  }
  else {
    return axios.get(`${local_host}/categorys/`, params);
  }
};

這個時候訪問 http://127.0.0.1:8080/#/app/home/index

發現不顯示商品分類了,是由於這涉及到了跨域問題,接下來就解決跨域的問題

 

drf跨域問題

後端服務器解決跨域問題的方法

(1)安裝模塊

pip install django-cors-headers

django-cors-headers 使用說明:https://github.com/ottoyiu/django-cors-headers

 (2)添加到INSTALL_APPS中

INSTALLED_APPS = (
    ...
    'coreschema',
 ... )

(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

CORS_ORIGIN_ALLOW_ALL = True

如今再訪問 http://127.0.0.1:8080/#/app/home/index   數據就能夠填充進來了

 

 在一級分類中設置爲True

 

 

6.3.vue展現商品列表頁數據

 商品列表頁會判斷咱們是serach仍是getGoods

getListData() {
                if(this.pageType=='search'){
                  getGoods({
                    search: this.searchWord, //搜索關鍵詞
                  }).then((response)=> {
                    this.listData = response.data.results;
                    this.proNum = response.data.count;
                  }).catch(function (error) {
                    console.log(error);
                  });
                }else {
                  getGoods({
                    page: this.curPage, //當前頁碼
                    top_category: this.top_category, //商品類型
                    ordering: this.ordering, //排序類型
                    pricemin: this.pricemin, //價格最低 默認爲‘’ 即爲不選價格區間
                    pricemax: this.pricemax // 價格最高 默認爲‘’
                  }).then((response)=> {

                    this.listData = response.data.results;
                    this.proNum = response.data.count;
                  }).catch(function (error) {
                    console.log(error);
                  });
                }

            },

說明:

(1)page分頁

page_size數量與前端一致

頁碼參數與起前端一致"page"

class GoodsPagination(PageNumberPagination):
    '''
    商品列表自定義分頁
    '''
    #默認每頁顯示的個數
    page_size = 12
    #能夠動態改變每頁顯示的個數
    page_size_query_param = 'page_size'
    #頁碼參數
    page_query_param = 'page'
    #最多能顯示多少頁
    max_page_size = 100

(2)過濾

top_category是商品的一級分類,須要傳入參數:一級分類的id

pricemin和pricemax與前端保持一致

獲取一級分類下的全部商品

# goods/filters.py

import django_filters

from .models import Goods
from django.db.models import Q

class GoodsFilter(django_filters.rest_framework.FilterSet):
    '''
    商品過濾的類
    '''
    #兩個參數,name是要過濾的字段,lookup是執行的行爲,‘小與等於本店價格’
    pricemin = django_filters.NumberFilter(name="shop_price", lookup_expr='gte')
    pricemax = django_filters.NumberFilter(name="shop_price", lookup_expr='lte')
    top_category = django_filters.NumberFilter(name="category", method='top_category_filter')

    def top_category_filter(self, queryset, name, value):
        # 無論當前點擊的是一級分類二級分類仍是三級分類,都能找到。
        return queryset.filter(Q(category_id=value) | Q(category__parent_category_id=value) | Q(
            category__parent_category__parent_category_id=value))

    class Meta:
        model = Goods
        fields = ['pricemin', 'pricemax']

(3)排序

GoodsListViewSet中ording與前端要一致

   #排序
    ordering_fields = ('sold_num', 'shop_price')

 (4)替換爲local_host

//獲取商品列表
export const getGoods = params => { return axios.get(`${local_host}/goods/`, { params: params }) }

(5)搜索

   #搜索
    search_fields = ('name', 'goods_brief', 'goods_desc')

 

如今就能夠從後臺獲取商品的數據了,主要功能

  • 分類過濾
  • 價格區間過濾
  • 顯示商品數量
  • 分頁
  • 搜索

 

 

全部代碼:

# MxShop/urls.py
__author__ = 'derek'


from django.urls import path,include,re_path
import xadmin
from django.views.static import serve
from MxShop.settings import MEDIA_ROOT
# from goods.view_base import GoodsListView

from rest_framework.documentation import include_docs_urls
from goods.views import GoodsListViewSet,CategoryViewSet
from rest_framework.routers import DefaultRouter

router = DefaultRouter()

#配置goods的url
router.register(r'goods', GoodsListViewSet,base_name='goods')
# 配置Category的url
router.register(r'categorys', CategoryViewSet, base_name="categorys")


urlpatterns = [
    path('xadmin/', xadmin.site.urls),
    path('api-auth/',include('rest_framework.urls')),
    path('ueditor/',include('DjangoUeditor.urls' )),
    #文件
    path('media/<path:path>',serve,{'document_root':MEDIA_ROOT}),
    #drf文檔,title自定義
    path('docs',include_docs_urls(title='仙劍奇俠傳')),
    #商品列表頁
    re_path('^', include(router.urls)),
]
MxShop/urls.py
# goods/filters.py

import django_filters

from .models import Goods
from django.db.models import Q

class GoodsFilter(django_filters.rest_framework.FilterSet):
    '''
    商品過濾的類
    '''
    #兩個參數,name是要過濾的字段,lookup是執行的行爲,‘小與等於本店價格’
    pricemin = django_filters.NumberFilter(name="shop_price", lookup_expr='gte')
    pricemax = django_filters.NumberFilter(name="shop_price", lookup_expr='lte')
    top_category = django_filters.NumberFilter(name="category", method='top_category_filter')

    def top_category_filter(self, queryset, name, value):
        # 無論當前點擊的是一級分類二級分類仍是三級分類,都能找到。
        return queryset.filter(Q(category_id=value) | Q(category__parent_category_id=value) | Q(
            category__parent_category__parent_category_id=value))

    class Meta:
        model = Goods
        fields = ['pricemin', 'pricemax']
goods/filters.py
# goods/serializers.py

from rest_framework import serializers
from .models import Goods,GoodsCategory


class CategorySerializer3(serializers.ModelSerializer):
    '''三級分類'''
    class Meta:
        model = GoodsCategory
        fields = "__all__"


class CategorySerializer2(serializers.ModelSerializer):
    '''
    二級分類
    '''
    #在parent_category字段中定義的related_name="sub_cat"
    sub_cat = CategorySerializer3(many=True)
    class Meta:
        model = GoodsCategory
        fields = "__all__"


class CategorySerializer(serializers.ModelSerializer):
    """
    商品一級類別序列化
    """
    sub_cat = CategorySerializer2(many=True)
    class Meta:
        model = GoodsCategory
        fields = "__all__"


#ModelSerializer實現商品列表頁
class GoodsSerializer(serializers.ModelSerializer):
    #覆蓋外鍵字段
    category = CategorySerializer()
    class Meta:
        model = Goods
        fields = '__all__'
goods/serializers.py
# googd/views.py

from rest_framework.views import APIView
from goods.serializers import GoodsSerializer,CategorySerializer
from .models import Goods,GoodsCategory
from rest_framework.response import Response
from rest_framework import mixins
from rest_framework import generics
from rest_framework.pagination import PageNumberPagination
from rest_framework import viewsets
from .filters import GoodsFilter
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters


class GoodsPagination(PageNumberPagination):
    '''
    商品列表自定義分頁
    '''
    #默認每頁顯示的個數
    page_size = 12
    #能夠動態改變每頁顯示的個數
    page_size_query_param = 'page_size'
    #頁碼參數
    page_query_param = 'page'
    #最多能顯示多少頁
    max_page_size = 100


class GoodsListViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
    '''
    商品列表,分頁,搜索,過濾,排序
    '''

    #這裏必需要定義一個默認的排序,不然會報錯
    queryset = Goods.objects.all()
    # 分頁
    pagination_class = GoodsPagination
    #序列化
    serializer_class = GoodsSerializer
    filter_backends = (DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter)

    # 設置filter的類爲咱們自定義的類
    #過濾
    filter_class = GoodsFilter
    #搜索
    search_fields = ('name', 'goods_brief', 'goods_desc')
    #排序
    ordering_fields = ('sold_num', 'shop_price')


class CategoryViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    '''
    list:
        商品分類列表數據
    '''

    queryset = GoodsCategory.objects.filter(category_type=1)
    serializer_class = CategorySerializer
goods/views.py

 

 

Django REST framework+Vue 打造生鮮超市(四)

Django REST framework+Vue 打造生鮮超市(三)

Django REST framework+Vue 打造生鮮超市(二)

Django REST framework+Vue 打造生鮮超市(一)

相關文章
相關標籤/搜索