1. 程式人生 > >Django REST framework電商專案筆記】第06章 商品類別功能

Django REST framework電商專案筆記】第06章 商品類別功能

將drf返回的資料對映到vue介面思路

1、處理商品的分類 2、目錄會有兩個介面

  • 一個是全部資料的介面,用於首頁的全部分類,一級-二級-三級
  • 另一個是獲取某一類的分類,以及商品數量 3、為商品通過大類進行過濾條件的過濾。價格,銷量的排序,分頁

開發商品類別介面

1、商品類別序列化:

class CategorySerializer(serializers.ModelSerializer):
    """
    商品類別序列化
    """
    class Meta:
        model = GoodsCategory
        fields = "__all__"

2、對分類進行篩選

class CategoryViewSet(mixins.ListModelMixin,
                      mixins.RetrieveModelMixin,
                      viewsets.GenericViewSet):
    """
    list:   商品分類列表資料
    retrieve:  獲取商品分類詳情
    """
	#上面的註釋要寫清楚,才能讓後面生成文件更方便
    queryset = GoodsCategory.objects.filter(category_type=1)
    serializer_class =
CategorySerializer

3、配置 url

router = DefaultRouter()

# 配置商品列表的路由
router.register(r'goods', GoodsAllViewSet, base_name="goods")

# 配置商品分類的路由
router.register(r'category', CategoryViewSet, base_name="category")

我這裡是/category,老師的 vue 檔案配置的 url 貌是 /categories,注意比較是否相同

如何讓一類資料包括二類資料

Serializer 中新增三級分類的 Serializer

"""
goods的外來鍵category --> 直接巢狀展示category表中的欄位
通過巢狀的方式實現序列化
"""
class CategorySerializer3(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = "__all__"


class CategorySerializer2(serializers.ModelSerializer):
    sub_cat = CategorySerializer3(many=True)
    class Meta:
        model = GoodsCategory
        fields = "__all__"


class CategorySerializer(serializers.ModelSerializer):
    """
    通過related_name的sub_cat呼叫
    """
    sub_cat = CategorySerializer2(many=True)
    class Meta:
        model = GoodsCategory
        fields = "__all__"
        

這裡的 sub_cat 是因為我們在自身的繼承關係中將這種關係進行了命名 goods 的 models.py:

    parent_category = models.ForeignKey("self", on_delete=models.CASCADE, null=True, blank=True, verbose_name="父類目級別", help_text="父目錄",
                                        related_name="sub_cat")

因為我們此時通過一類拿到的二類有很多,所以必須加上 many = True 的引數

問題又來了: 現在我們獲取的是所有的category,如何獲取具體某一個下面的。 點選生鮮食品,左側出現的是生鮮食品下面的具體分類。 目標: 獲取列表頁裡面的詳情頁 讓我們的 CategoryViewSet 多繼承一個 mixins.retrievemodelmixin

這裡我們需要遵循restful api 對於某一個商品詳情獲取的推薦

GET /category/ID:獲取某個指定分類的資訊

其實這個工作 viewset 已經幫我們做了,一但我們進行了register的註冊。只要我們繼承了 RetrieveModelMixin 就可以直接通過id進行獲取。 http://127.0.0.1:8000/category/1/

設定伺服器完成跨域

安裝 django-cors-headers

pip install django-cors-headers

新增進安裝的app中

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

新增到 settings 的中介軟體 middleware 中,要放在 CsrfViewMiddleware 之前

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',    # 跨域中介軟體配置
    'django.middleware.csrf.CsrfViewMiddleware',
    ...
]

新增引數為 true 及設定白名單

CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
    '127.0.0.1:3000'
)

view 中將分頁的引數修改為 page 與前端 vue 保持一致

    page_query_param = "page"

引數top_category就是我們的第一級別。它是將我們引數中的id值傳入 因此在後臺我們也需要配套的做一個category的過濾器 如何獲取一級分類下的所有商品 goods/filters.py:class GoodsFilter

 top_category = filters.NumberFilter(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))

然後將 queryset return 回去 pricemin 以及 pricemax 與我們的前端程式碼中的一致 所以修改goods/filters.py中的與前端保持一致 分頁資料中會自帶一個count值

設定分頁size與前端保持一致

class GoodsPagination(PageNumberPagination):
    """
    商品列表分頁
    """

    page_size = 12
    page_size_query_param = 'page_size'
    page_query_param = 'page'
    max_page_size = 100