第五课 Vue+Django rest framework生鲜商品类别数据和vue展示

第五课 Vue+Django rest framework生鲜商品类别数据和vue展示

第一节 django view实现商品分类数据

1.1 categorys Api接口实现

  1. goods下views.py下写一个CategoryViewSet
from goods.serializer import GoodsSerializer, GoodsCategorySerializer
from .models import Goods, GoodsCategory
class CategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    list :
        商品分类列表数据
    """
    queryset = GoodsCategory.objects.all()
    serializer_class = GoodsCategorySerializer
  1. Serializer.py实现GoodsCategorySerializer
class GoodsCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = "__all__"
  1. 配置url.py
from goods.views import GoodsListViewset, CategoryViewSet
router.register(r'categorys', CategoryViewSet, basename="categorys")
  1. 运行,访问api。看下能否获取全部数据。
python manage.py runserver
http://127.0.0.1:8000/categorys/

1.2 categorys Api查询需要数据

  1. 如果要查询某一层级分类的数据, 修改CategoryViewSet
class CategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    list :
        商品分类列表数据
    """
    # queryset = GoodsCategory.objects.all()
    queryset = GoodsCategory.objects.filter(category_type=1)
    serializer_class = GoodsCategorySerializer
  1. **如何通过一类分类拿到二类分类的数据呢?并通过二类分类拿到三类分类数据?**记得我们model中有个字段。related_name="sub_cat"就是我们拿到下级数据的关键。一类对象.sub_cat就可以把下级数据取出来。
parent_category = models.ForeignKey("self", null=True, blank=True, verbose_name="父类目级别", help_text="父目录", related_name="sub_cat", on_delete=models.CASCADE)

在这里插入图片描述

  1. 修改Serializer.py实现上图的层级嵌套数据输出。这里下级多个必须加上many=True,防止报错
class GoodsCategorySerializer3(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategory
        fields = "__all__"


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


class GoodsCategorySerializer(serializers.ModelSerializer):
    sub_cat = GoodsCategorySerializer2(many=True)
    class Meta:
        model = GoodsCategory
        fields = "__all__"
  1. 这里获取某个具体分类下的具体商品也不需要我们重新定义视图函数和路由。直接在views.py下CategoryViewSet,多继承一个mixins.RetrieveModelMixin即可, 它内部帮我们已经实现了。
class CategoryViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    """
    list :
        商品分类列表数据
    """
    # queryset = GoodsCategory.objects.all()
    queryset = GoodsCategory.objects.filter(category_type=1)
    serializer_class = GoodsCategorySerializer
  1. 到数据库中查看category_type=1的category的id。直接访问可以看到查询出的数据即可:http://127.0.0.1:8000/categorys/57/

1.3 categorys Api和Vue接口调试

  1. 前端category在MxShop\online-store\src\views\head\head.vue中定义。
  2. 通过getMenu调用\MxShop\online-store\src\api\api.js中的函数getCategory。
  3. 本项目所有与drf后台交互的api接口全定义在\MxShop\online-store\src\api\api.js文件中。
  4. 源码中实际上从线上的环境中获取的。let host = ‘http://shop.projectsedu.com’;
  5. 如果要调试。可以重新给个变量,调试哪个接口就给它替换就行。let localhost = ‘http://127.0.0.1:8000’;
  6. 重启后台和前台项目。发现没有数据填充。报错跨域访问的问题。跨端口了实际上跨域了。
    • 可以通过前段代理解决
    • 也可以通过服务器的设置解决
Access to XMLHttpRequest at 'http://127.0.0.1:8000/categorys/' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
  1. 设置drf的跨域问题。到github查一下django cors headers。找到解决方案。settings.py中配置
    • python -m pip install django-cors-headers
# 1. 注册
INSTALLED_APPS = [
    ...
    'corsheaders',
    ...
]
# 2. 'corsheaders.middleware.CorsMiddleware'要尽量放在前面
MIDDLEWARE = [
    ...
    'corsheaders.middleware.CorsMiddleware',
    ...
]
# 3. CORS_ORIGIN_ALLOW_ALL=True 默认为false的
CORS_ORIGIN_ALLOW_ALL=True
  1. 重新刷新页面,获取数据正常。

  2. http://127.0.0.1:8000/xadmin 到后台管理系统取喜欢的一级商品分类作为导航。
    在这里插入图片描述

  3. 刷新前端页面,导航数据就可以但看到了。

第二节 django view实现商品列表页数据

2.1 商品列表页接口适配

  1. 修改后台页面中views.py中的类GoodsPagination。page_query_param = ‘page’
  2. MxShop\online-store\src\views\list\list.vue中展示函数。getListData
  3. 这里我们需要找到一级分类下所有二级分类,以及二级分类所有的商品。这里可以用filter自定义自己方法来写自己过滤逻辑。
from django_filters import rest_framework as filters
from .models import Goods
from django.db.models import Q


class GoodsFilter(filters.FilterSet):
    """
    商品的过滤类
    """
    pricemin = filters.NumberFilter(field_name="shop_price", lookup_expr='gte')
    pricemax = filters.NumberFilter(field_name="shop_price", lookup_expr='lte')
    # 模糊查询 忽略大小写icontains
    # name = filters.CharFilter(field_name="name", lookup_expr='icontains')
    top_category = filters.NumberFilter(method="top_category_filter")

    # 这是三个参数是默认传递进来的queryset, name, value
    def top_category_filter(self, queryset, name, value):
        queryset = queryset.filter(Q(category_id=value) | \
                                   Q(category__parent_category_id=value) | \
                                   Q(category__parent_category__parent_category_id=value))
        return queryset


    class Meta:
        model = Goods
        fields = ['pricemin', 'pricemax']
  1. views.py字段适配GoodsListViewset
class GoodsListViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    商品列表页,分页,搜索,过滤,排序
    """
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination

    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_class = GoodsFilter
    # 查询和排序这里可以加一些正则的语法
    search_fields = ['name', 'goods_brief', 'goods_desc']
    ordering_fields = ['sold_num', 'shop_price']
    # filterset_fields = ['name', 'shop_price']
  1. 刷新前端页面,测试。价格排序,搜索,价格区间,一类下的商品。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值