Django+Vue打造購物網站(四)


首頁商品類別數據顯示

商品分類接口

大概需要兩個,一個顯示三個類別

一個顯示類別及類別下的全部商品

現在開始寫商品的接口
首先編寫三個分類的serializer

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__"

然后編寫視圖函數

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

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

配置url

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

注釋的內容會顯示在文檔中
mixins.RetrieveModelMixin可以查看單個分類
前面已經配置過文檔的url了

vue展示商品分類數據

接口相關代碼都放在src/api/api.js里面,調試接口的時候我們首先需要新建一個自己的host,然后替換要調試的host

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

替換商品類別默認的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);
  }
};

打開瀏覽器,可以看到,數據並沒有顯示出來,
是因為這涉及到了跨域問題,接下來就解決跨域的問題

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

https://github.com/ottoyiu/django-cors-headers
安裝模塊

pip install django-cors-headers

添加到INSTALL_APPS中

INSTALLED_APPS = (
    'corsheaders',
)

添加中間件
CorsMiddleware應盡可能放置,特別是在可以生成響應的任何中間件之前,例如Django CommonMiddleware或Whitenoise WhiteNoiseMiddleware。如果不是之前,它將無法將CORS標頭添加到這些響應中。

此外,如果你使用CORS_REPLACE_HTTPS_REFERER它應該放在Django之前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',
]

在Django設置中配置了中間件。您必須添加允許執行跨站點請求的主機 CORS_ORIGIN_WHITELIST,或者設置CORS_ORIGIN_ALLOW_ALL以True 允許所有主機。

這里先允許所有主機跨域,等部署后可以直接將主機ip或域名添加到CORS_ORIGIN_WHITELIST

# 跨域
CORS_ORIGIN_ALLOW_ALL = True

打開瀏覽器進行訪問,會發現導航里面沒有數據,這是因為后台沒有進行設置,需要在后台進行設置

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);
          });
        }

    },

根據前端內容修改后端分頁的參數

class GoodsPagination(PageNumberPagination):
    '''
    商品列表自定義分頁
    '''
    # 默認每頁顯示的個數
    page_size = 12
    # 可以動態改變每頁顯示的個數
    page_size_query_param = 'page_size'
    # 頁碼參數 http://127.0.0.1:8000/goods/?page=2&page_size=30
    page_query_param = 'page'
    # 每頁最多能顯示多少體條
    # 僅當 page_size_query_param 設置時有效
    max_page_size = 20

通過vue代碼可以看到url參數中有一個top_category
需要給這個參數添加過濾方法

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

    # 自定義過濾方法,不管當前點擊的是一級分類二級分類還是三級分類,都能找到。
    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']

通過瀏覽器可以進行測試
在后台查找某一分類下的商品,然后在前台點擊進行對比

修改排序
前台是按照銷量和價格進行排序的,修改后端代碼

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM