商品列表页、详情页功能实现
:项⽬介绍,环境搭建
:model设计
:xadmin后台管理
:商品列表页
:商品类别数据显⽰
⼀、商品列表页
1、 goods/serializers.py 序列化
from rest_framework import serializers
dels import GoodsCategory
class CategorySerializer3(serializers.ModelSerializer):
'''三级分类'''
class Meta:
model = GoodsCategory
fields = "__all__"django登录注册功能
class CategorySerializer2(serializers.ModelSerializer):
'''⼆级分类'''
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 GoodsSerializer(serializers.ModelSerializer):
category = CategorySerializer()  #覆盖默认的category序列化字段
images = GoodsImageSerializer(many=True)
# images名称是GoodsImage中goods = models.ForeignKey(Goods, verbose_name="商品", related_name="images")
#  related_name="images" 中的images
class Meta:
model = Goods
fields = "__all__"# 取所有字段
2、goods/filter
# 官⽅⽂档:adthedocs.io/en/stable/guide/rest_framework.html#quickstart
import django_filters
from dels import Q
from .models import Goods
class GoodsFilter(st_framework.FilterSet):
"""
商品的过滤类
"""
# ⾃从 django-filter2.0之后将Filter的name字段更名为 field_name(本项⽬⽤的django-filter2.3)
pricemin = django_filters.NumberFilter(field_name='shop_price', help_text="最低价格",lookup_expr='gte')
pricemax = django_filters.NumberFilter(field_name='shop_price', lookup_expr='lte')
top_category = django_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)) #
class Meta:
model = Goods
fields = ['pricemin', 'pricemax', 'is_hot', 'is_new']
3、goods/views.py
from .serializers import GoodsSerializer, CategorySerializer, HotWordsSerializer, BannerSerializer
from rest_framework import mixins
from rest_framework import filters
from rest_framework.pagination import PageNumberPagination
from st_framework import DjangoFilterBackend
from rest_framework import viewsets
# .models:加 . 的好处表⽰从当前的goods⽬录下models,加速查且不容易失败
from .models import Goods, GoodsCategory
from .filters import GoodsFilter
# ⾃定义分页
class GoodsPagination(PageNumberPagination):
page_size = 12                        # 每⼀页显⽰多少条数据
page_query_param = "page"# url中指定显⽰哪⼀页的数据    ?page=2
page_size_query_param = 'page_size'# 临时控制每页显⽰⼏条数据    ?page=2&page_size=2
max_page_size = 100                  # 每页最多显⽰多少条数据,针对上⾯的size
class GoodsListViewSet(mixins.ListModelMixin,mixins.RetrieveModelMixin, viewsets.GenericViewSet): """
商品列表页, 分页,搜索,过滤,排序
"""
queryset = Goods.objects.all()#
serializer_class = GoodsSerializer#
pagination_class = GoodsPagination#
# authentication_classes = (TokenAuthentication, )  # 商品列表页是公开的,不需要授权认证
filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)#
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:
商品分类列表数据
retrieve:
获取商品分类详情
"""
queryset = GoodsCategory.objects.filter(category_type=1) # 获取第⼀类数据
serializer_class = CategorySerializer
4、urls.py
# 配置Category的url
⼆、drf跨域问题
后端服务器解决跨域问题的⽅法
1、安装模块
pip install django-cors-headers
2、添加到INSTALL_APPS中
INSTALLED_APPS = (
...
'coreschema',
... )
3、添加中间件
必须在CsrfViewMiddleware之前。我们直接放在第⼀个位置就好了
4、settings中相关设置
CORS_ORIGIN_ALLOW_ALL = True
三、商品详情页
商品详情页功能
1、商品轮播图goods/serializers.py
from rest_framework import serializers
dels import Goods,  GoodsImage
# 商品详情页轮播图
class GoodsImageSerializer(serializers.ModelSerializer):
class Meta:
model = GoodsImage
fields = ("image", )
class GoodsSerializer(serializers.ModelSerializer):
category = CategorySerializer()  #覆盖默认的category序列化字段
images = GoodsImageSerializer(many=True)
# images名称是GoodsImage中goods = models.ForeignKey(Goods, verbose_name="商品", related_name="images")
#  related_name="images" 中的images
class Meta:
model = Goods
fields = "__all__"# 取所有字段
2、热销商品
只需要在过滤器中增加“is_hot”就可以了
goods/filters.py⾥的GoodsFilter添加“is_hot”
class Meta:
model = Goods
fields = ['pricemin', 'pricemax','is_hot']
3、⽤户收藏
Custom permissions:
Attributes:
HiddenField:
HiddenField的值不依靠输⼊,⽽需要设置默认的值,不需要⽤户⾃⼰post数据过来,也不会显式返回给⽤户,最常⽤的就是user!!
我们在收藏某件商品的时候,后台要获取到当前的⽤户;相当于前台只需要传递过来⼀个商品的ID即可;
那么在后台我根据当前的登⼊⽤户和当前的商品ID即可判断⽤户是否收藏过该商品;这就是⼀个联合唯⼀主键的判断;这同样需要使⽤HiddenField。(1)序列化
user_operation/serializers.py
from rest_framework import serializers
from dels import UserFav
from rest_framework.validators import UniqueTogetherValidator
class UserFavSerializer(serializers.ModelSerializer):
#获取当前登录的⽤户
user = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)
class Meta:
#validate实现唯⼀联合,⼀个商品只能收藏⼀次
validators = [
UniqueTogetherValidator(
queryset=UserFav.objects.all(),
fields=('user', 'goods'),
#message的信息可以⾃定义
message="已经收藏"
)
]
model = UserFav
#收藏的时候需要返回商品的id,因为取消收藏的时候必须知道商品的id是多少
fields = ("user", "goods",'id')
(2)user_operation/views.py
from rest_framework import viewsets
from rest_framework import mixins
from rest_framework.permissions import IsAuthenticated
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.authentication import SessionAuthentication
from .models import UserFav, UserLeavingMessage, UserAddress
from utils.permissions import IsOwnerOrReadOnly
from .serializers import UserFavSerializer, UserFavDetailSerializer, AddressSerializer, LeavingMessageSerializer
class UserFavViewset(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin,
mixins.DestroyModelMixin, viewsets.GenericViewSet):
"""
list:
获取⽤户收藏列表
retrieve:
判断某个商品是否已经收藏
create:
收藏商品
  destory:
    取消收藏
"""
# queryset = UserFav.objects.all() # 不能获取所有⼈的UserFav
serializer_class = UserFavSerializer
# IsAuthenticated:⽤户必须登录,IsOwnerOrReadOnly:必须是当前的⽤户在操作    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
# auth使⽤来做⽤户认证的
authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication) # 搜索的字段
lookup_field = "goods_id"
# 获取当前⽤户的 UserFav
def get_queryset(self):
return UserFav.objects.filter(quest.user)
(3)配置url
# 配置⽤户收藏的url

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。