Django REST framework+Vue 打造生鲜超市(五)
六、商品類別數據展示
6.1. 商品類別數據接口
(1)商品分類有兩個接口:
一種是全部分類:一級二級三級
?
?
??一種是某一類的分類以及商品詳細信息:
?
?開始寫商品分類的接口
(2)序列化
給分類添加三級分類的serializer
?goods/serializers.py
from rest_framework import serializers from .models import Goods,GoodsCategoryclass CategorySerializer3(serializers.ModelSerializer):'''三級分類'''class Meta:model = GoodsCategoryfields = "__all__"class CategorySerializer2(serializers.ModelSerializer):'''二級分類'''#在parent_category字段中定義的related_name="sub_cat" sub_cat = CategorySerializer3(many=True)class Meta:model = GoodsCategoryfields = "__all__"class CategorySerializer(serializers.ModelSerializer):"""商品一級類別序列化"""sub_cat = CategorySerializer2(many=True)class Meta:model = GoodsCategoryfields = "__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-headersdjango-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.pyimport django_filtersfrom .models import Goods from django.db.models import Qclass 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 = Goodsfields = ['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')?
現在就可以從后臺獲取商品的數據了,主要功能
- 分類過濾
- 價格區間過濾
- 顯示商品數量
- 分頁
- 搜索
?
所有代碼:
按 Ctrl+C 復制# 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
代碼 按 Ctrl+C 復制代碼# 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
?
轉載于:https://www.cnblogs.com/daluozi/p/9467344.html
總結
以上是生活随笔為你收集整理的Django REST framework+Vue 打造生鲜超市(五)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 06一键直达:一键整理、秒搜、秒开任何文
- 下一篇: 数学模型与数据结构的丝连