vue一级分类和耳机分类_【Vue+DRF生鲜电商】10.商品分类层级获取,Vue跨域请求商品分类...
歡迎訪問我的博客專題
源碼可訪問 Github 查看
DRF實現商品分類獲取
實現商品分類層級結構顯示
商品類別ViewSet
在商品類別中,不需要對類別進行分頁,因為類別的數據量不大,只要在數據量很大的時候才能分頁,所以前面需要去掉全局分頁配置,否則會影響這兒的結果。
修改 views.py 增加分類的視圖
class CategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
# 注釋很有用,在drf文檔中,可以自動提取出來
"""
list:
商品分類列表
"""
queryset = GoodsCategory.objects.all() # 取出所有分類,沒必要分頁,因為分類數據量不大
serializer_class = CategorySerializer # 使用商品類別序列化類,寫商品的分類外鍵已有,直接調用
該序列化類可以直接使用之前商品列表分類外鍵已經創建好的,不用再新建,下方是已有的代碼內容
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = GoodsCategory
fields = '__all__'
商品類別URL配置
修改主 urls.py ,在router中注冊分類的url
from rest_framework.routers import DefaultRouter
from goods.views import GoodsListView, GoodsListViewSet, CategoryViewSet
# 創建一個路由器并注冊我們的視圖集
router = DefaultRouter()
router.register(r'goods', GoodsListViewSet, base_name='goods') # 配置goods的url
router.register(r'categories', CategoryViewSet, base_name='categories') # 配置分類的url
urlpatterns = [
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls')), # drf 認證url
path('ckeditor/', include('ckeditor_uploader.urls')), # 配置富文本編輯器url
path('', include(router.urls)), # API url現在由路由器自動確定。
# DRF文檔
path('docs/', include_docs_urls(title='DRF文檔')),
]
image.png
但是,這些分類數據都是一起顯示出來的,沒有層次結構。
層次化商品類別
首先訪問 http://127.0.0.1:8000/goods/ 記錄下每一種商品的分類外鍵數據,因為之后要修改分類的序列化類,可以做下對比
image.png
分析:在前端頁面上,拿分類數據時,首先是拿到一類分類,二級分類是在一級分類下面的,三級分類是二級分類下面的,可以看出,分類數據是有個層次結構的。
image.png
ViewSet只獲取一級分類
既然這樣,我們就可以在視圖中指定只獲取一級分類數據。
修改 views.py
class CategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
# 注釋很有用,在drf文檔中
"""
list:
商品分類列表
"""
# queryset = GoodsCategory.objects.all() # 取出所有分類,沒必要分頁,因為分類數據量不大
queryset = GoodsCategory.objects.filter(category_type=1) # 只獲取一級分類數據
serializer_class = CategorySerializer # 使用商品類別序列化類,寫商品的分類外鍵已有,直接調用
image.png
那怎么才能通過一級分類獲取到二級分類數據呢?之前寫商品列表需要顯示分類外鍵內容時,通過覆寫category自定義序列化類實現。
序列化二級分類
在分類模型中,有個parent_category = models.ForeignKey('self', null=True, blank=True, verbose_name='父級目錄', help_text='父級目錄', on_delete=models.CASCADE, related_name='sub_category')字段,也就是可以通過sub_category字段獲取子類對象。序列化類的字段也需要和這個字段保持一樣。
修改 serializers.py
class CategorySerializer2(serializers.ModelSerializer):
class Meta:
model = GoodsCategory
fields = '__all__'
class CategorySerializer(serializers.ModelSerializer):
sub_category = CategorySerializer2(many=True) # 通過一級分類獲取到二級分類,由于一級分類下有多個二級分類,需要設置many=True
class Meta:
model = GoodsCategory
fields = '__all__'
image.png
序列化三級分類
三級分類也是使用一樣的辦法,因為分類數據的格式都是一樣的
修改 serializers.py ,增加三級分類序列化
class CategorySerializer3(serializers.ModelSerializer):
class Meta:
model = GoodsCategory
fields = '__all__'
class CategorySerializer2(serializers.ModelSerializer):
sub_category = CategorySerializer3(many=True) # 通過二級分類獲取三級分類
class Meta:
model = GoodsCategory
fields = '__all__'
class CategorySerializer(serializers.ModelSerializer):
sub_category = CategorySerializer2(many=True) # 通過一級分類獲取到二級分類,由于一級分類下有多個二級分類,需要設置many=True
class Meta:
model = GoodsCategory
fields = '__all__'
image.png
通過以上修改后,商品列表頁也會跟著發生變化,顯示的商品分類,會增加子類的顯示
image.png
顯示某個分類詳情(包含其子類)
類似于獲取詳情頁
修改視圖,增加mixins.RetrieveModelMixin這樣一個mixins
class CategoryViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
# 注釋很有用,在drf文檔中
"""
list:
商品分類列表
"""
# queryset = GoodsCategory.objects.all() # 取出所有分類,沒必要分頁,因為分類數據量不大
queryset = GoodsCategory.objects.filter(category_type=1) # 只獲取一級分類數據
serializer_class = CategorySerializer # 使用商品類別序列化類,寫商品的分類外鍵已有,直接調用
這個繼承主要是獲取某個對象的詳情,且這只需要這樣寫即可。
Restful Api規范中要獲取某個對象的詳情,只需要在其后面添加某個對象的ID即可。
DRF已經做好了,不需要手動配置獲取詳情的URL,只需要在ViewSe中繼承mixins.RetrieveModelMixin即可,其他什么都不需要
image.png
image.png
在Vue中獲取分類API顯示前端
vue中存放分類菜單的位置在 src/views/head/head.vue 中
沒有數據,按 F12 打開打開Console可以看到錯誤內容
Access to XMLHttpRequest at 'http://localhost:8000/categories/' from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
也就是不允許跨域請求。因為服務器啟動的端口是8000,而Vue啟動的是8080端口。就需要配置服務器的跨域(前端也可以配置跨域)。
跨域處理django-cors-headers
解決辦法: 查看 https://github.com/ottoyiu/django-cors-headers (Django應用程序處理跨源資源共享(CORS)所需的服務器頭),下方有說明使用方法
使用pip安裝包,pip install django-cors-headers
將corsheaders應用添加到APPS中
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 添加drf應用
'rest_framework',
'django_filters',
# Django跨域解決
'corsheaders',
# 注冊富文本編輯器ckeditor
'ckeditor',
# 注冊富文本上傳圖片ckeditor_uploader
'ckeditor_uploader',
'users.apps.UsersConfig',
'goods.apps.GoodsConfig',
'trade.apps.TradeConfig',
'user_operation.apps.UserOperationConfig'
]
還需要添加一個中間件類來監聽響應:
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # corsheaders跨域
'django.middleware.common.CommonMiddleware', # corsheaders跨域
'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',
]
CorsMiddleware應該放在盡可能前面的位置,尤其是在任何能夠生成響應的中間件之前,比如Django的CommonMiddleware或Whitenoise的WhiteNoiseMiddleware。如果不在這之前,它將不能將CORS頭添加到這些響應中。
另外,如果正在使用CORS_REPLACE_HTTPS_REFERER,那么它應該放在Django的CsrfViewMiddleware之前。
全局配置:
Django設置中配置中間件的行為。必須將允許執行跨站點請求的主機添加到CORS_ORIGIN_WHITELIST,或者將CORS_ORIGIN_ALLOW_ALL設置為True以允許所有主機。
CORS_ORIGIN_ALLOW_ALL:如果是True,白名單將不被使用,所有的連接將被接受。默認值為False。
CORS_ORIGIN_WHITELIST:授權發出跨站點HTTP請求的源主機名列表。值“null”也可以出現在這個列表中,并將與“隱私敏感上下文”中使用的Origin: null頭匹配,例如當客戶機從file:// domain運行時。默認為[]。
修改 settings.py ,增加CORS配置
# 跨域CORS設置
# CORS_ORIGIN_ALLOW_ALL = False # 默認為False,如果為True則允許所有連接
CORS_ORIGIN_WHITELIST = ( # 配置允許訪問的白名單
'localhost:8080',
'127.0.0.1:8080',
)
image.png
Vue顯示分類菜單流程分析
使用axios請求分類數據的api: src/api/api.js
//獲取商品類別信息
export const getCategory = params => {
if ('id' in params) {
return axios.get(`${local_host}/categories/` + params.id + '/');
}
else {
return axios.get(`${local_host}/categories/`, params);
}
};
在這個代碼中,如果沒有獲取到id,則請求所有的分類,否則請求指定分類id的詳情。
從getCategory拿到數據之后,取results的值(也就是Django Api的是數據部分)賦值給,allMenuLabel,默認為[], head/head.vue
getMenu() {//獲取菜單
getCategory({
params: {}
}).then((response) => {
console.log('輸出分類列表請求結果:');
console.log(response.data);
this.allMenuLabel = response.data.results
})
.catch(function (error) {
console.log(error);
});
},
image.png
進行allMenuLabel在vue中 for循環的遍歷,顯示類別的name
全部商品分類
{{item.name}}
{{second_item.name}}
{{third_item.name}}
遍歷三級,顯示每一級的分類信息。
分類顯示到導航
到目前為止,分類可以正常顯示,但是上方的tab沒有顯示一項,就只有首頁,對應源碼如下, head/head.vue
在后臺中,所有的分類對象is_tab字段都是為False,默認不顯示在導航中。在Django Admin中設置一些一級分類is_tab為True
修改 goods/admin.py ,設置商品類別后臺
from django.contrib import admin
from .models import GoodsCategory, Goods
from django.apps import apps
@admin.register(GoodsCategory)
class GoodsCategoryAdmin(admin.ModelAdmin):
list_display = ['name', 'category_type', 'is_tab', 'parent_category'] # 列表頁顯示
list_display_links = ('name', 'parent_category',) # 列表頁外鍵鏈接,字段需在list_display中
list_editable = ('is_tab',) # 列表頁可編輯
list_filter = ('category_type',) # 列表頁可篩選
search_fields = ('name', 'desc') # 列表頁可搜索
all_models = apps.get_app_config('goods').get_models()
for model in all_models:
try:
admin.site.register(model)
except:
pass
image.png
image.png
總結
以上是生活随笔為你收集整理的vue一级分类和耳机分类_【Vue+DRF生鲜电商】10.商品分类层级获取,Vue跨域请求商品分类...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python财务预算分析_财码Pytho
- 下一篇: bdphp在线订购是真的么_《瑞评》33