01用户模块模型定义_哔哩哔哩_bilibili 本博客借鉴至大佬的视频学习笔记
用户模块及商品数据表结构设计
- from ckeditor.fields import RichTextField # pip install django-ckeditor
- from django.db import models
-
- # Create your models here.
- # from wx.richtext import RichTextField
-
- from common.db import BaseModel
-
-
- class GoodsGroup(BaseModel):
- """商品分类"""
- name = models.CharField(verbose_name="分类名称", help_text="分类名称", max_length=15,blank=True,null=True)
- image = models.CharField(verbose_name="图片链接", help_text="图片链接", max_length=200, blank=True, null=True)
- status = models.BooleanField(verbose_name="是否启用", help_text="是否启用", default=False,blank=True,null=True)
-
- class Meta:
- db_table = 'goods_group'
- verbose_name = "商品分类表"
- verbose_name_plural = verbose_name
-
- def __str__(self):
- return self.name
-
-
- class Goods(BaseModel):
- """商品"""
- group = models.ForeignKey('GoodsGroup', verbose_name="分类", help_text="分类", max_length=15, on_delete=models.CASCADE)
- image = models.CharField(verbose_name="图片链接", help_text="图片链接", max_length=200, blank=True, null=True)
- title = models.CharField(verbose_name="标题", help_text="标题", max_length=20, blank=True,null=True)
- desc = models.CharField(verbose_name="商品描述", help_text="商品描述", max_length=200, blank=True,null=True)
- price = models.DecimalField(verbose_name="商品价格", help_text="商品价格", max_digits=10, decimal_places=2, blank=True,null=True)
- cover = models.ImageField(verbose_name="封面图链接", help_text="封面图链接", max_length=200, blank=True,null=True)
- stock = models.IntegerField(verbose_name="库存", help_text="库存", blank=True, null=True, default=1)
- sales = models.IntegerField(verbose_name="销量", help_text="销量", blank=True, null=True, default=0)
- is_on = models.BooleanField(verbose_name="是否上架", help_text="是否上架", blank=True, null=True, default=False)
- recommend = models.BooleanField(verbose_name="是否推荐", help_text="是否推荐", blank=True, null=True, default=False)
-
- class Meta:
- db_table = 'goods'
- verbose_name = '商品表'
- verbose_name_plural = verbose_name
-
- def __str__(self):
- return self.title
-
-
- class Detail(BaseModel):
- """商品详情"""
- goods = models.OneToOneField('Goods', verbose_name="商品", on_delete=models.CASCADE, max_length=200)
- producer = models.CharField(verbose_name='厂商', help_text='厂商', max_length=200, blank=True,null=True)
- norms = models.CharField(verbose_name='规格', help_text='规格', max_length=200, blank=True,null=True)
- details = RichTextField(verbose_name='商品详情', help_text='商品详情', max_length=200,blank=True,null=True)
-
- class Meta:
- db_table = 'details'
- verbose_name = '详情'
- verbose_name_plural = verbose_name
-
- def __str__(self):
- return self.goods
-
-
- class GoodsBanner(BaseModel):
- """商品轮播图"""
- title = models.CharField(verbose_name='轮播图名称', help_text='轮播图名称', max_length=20, blank=True)
- image = models.ImageField(verbose_name='轮播图链接', help_text='轮播图链接', max_length=200, blank=True)
- # url = models.CharField(verbose_name='跳转的地址',help_text='跳转的地址',max_length=200,blank=True)
- status = models.BooleanField(verbose_name='是否启用', help_text='是否启用', default=False,blank=True,null=True)
- seq = models.IntegerField(verbose_name='顺序', help_text='顺序', default=1, blank=True,null=True)
-
- class Meta:
- db_table = 'banner'
- verbose_name = '首页商品轮播'
- verbose_name_plural = verbose_name
-
- def __str__(self):
- return self.title
-
-
- class Collect(models.Model):
- """商品收藏"""
- user = models.ForeignKey('users.User', help_text='用户ID', verbose_name='用户ID', on_delete=models.CASCADE,blank=True,null=True)
- goods = models.ForeignKey('goods.Goods', help_text="商品ID", verbose_name="商品ID", on_delete=models.CASCADE,blank=True,null=True)
-
- class Meta:
- db_table = 'collect'
- verbose_name = "收藏商品"
- verbose_name_plural = verbose_name
-
- def __str__(self):
- return self.goods
Django自带admin配置
- from django.contrib import admin
- from .models import GoodsGroup,Goods,Detail,GoodsBanner,Collect
- # Register your models here.
-
- @admin.register(GoodsGroup)
- class GoodsGroupAdmin(admin.ModelAdmin):
- list_display = ['name','status']
-
- @admin.register(Goods)
- class GoodsAdmin(admin.ModelAdmin):
- list_display = ['title','group','price','stock','sales','is_on']
-
- @admin.register(Detail)
- class DetailGroupAdmin(admin.ModelAdmin):
- list_display = ['goods', 'producer','norms']
-
- @admin.register(GoodsBanner)
- class GoodsBannerAdmin(admin.ModelAdmin):
- list_display = ['title', 'status']
-
- @admin.register(Collect)
- class CollectAdmin(admin.ModelAdmin):
- list_display = ['user', 'goods']
商品首页接口实现
- class IndexView(APIView):
- """首页数据展示"""
- def get(self,request):
- """返回轮播图、商品分类"""
- group = GoodsGroup.objects.filter(status=True)
- groupSer =GoodsGroupSerializer(group,many=True)
- # 轮播图
- banner = GoodsBanner.objects.filter(status=True)
- bannerSer = GoodsBannerSerializer(banner,many=True)
- # 推荐的商品
- goods = Goods.objects.filter(recommend=True)
- goodsSer = GoodsSerializer(goods,many=True)
- # 返回数据
- result = {
- 'banner': bannerSer.data,
- 'goods':goodsSer.data,
- 'group':groupSer.data
- }
- return Response({"message":'ok','data':result},status=status.HTTP_200_OK)
-
- # 商品首页
- path('index/', IndexView.as_view()),
商品列表获取和分类排序接口
- # view
- class GoodsView(ReadOnlyModelViewSet):
- """"商品列表接口"""
- serializer_class = GoodsSerializer
- # 选择上架的商品
- queryset = Goods.objects.filter(is_on=True),
- # 实现商品分类和推荐类过滤
- filterset_fields = ('group','recommend')
- # 通过价格和销量排序
- ordering_fields =('sales','price','create_time')
-
- # url
- # 商品列表接口
- path('goods/', GoodsView.as_view({"get":'list'})),
- # 单个商品获取
- path('goods/
/' , GoodsView.as_view({"get":'retrieve'})), -
- # setting
- # 过滤器信息配置、排序器配置
- 'DEFAULT_FILTER_BACKENDS':['django_filters.rest_framework.DjangoFilterBackend',
- 'rest_framework.filters.OrderingFilter']
-
- # 注册
- 'django_filters',
商品的收藏与取消收藏接口
- # view
- class CollectView(mixins.RetrieveModelMixin,
- mixins.CreateModelMixin
- ,mixins.ListModelMixin,mixins.DestroyModelMixin,GenericViewSet):
- """
- 商品收藏与取消
- create: 收藏
- delete: 取消
- list: 收藏列表
- """
- queryset = Collect.objects.all()
- serializer_class = CollectSerializer
- permission_classes = [IsAuthenticated,CollectPermissions]
- filterset_fields = ("user",)
-
- def create(self, request, *args, **kwargs):
- # 获取请求参数
- user = request.user
- params_user_id = request.data.get('user')
- # 检验请求参数中的id是否当前登录的用户ID
- if user.id != params_user_id:
- return Response({'error':'你没有用户权限访问该信息'},status=status.HTTP_400_BAD_REQUEST)
- return super().create(request, *args, **kwargs)
-
- def list(self, request, *args, **kwargs):
- """商品收藏列表"""
- queryset = self.filter_queryset(self.get_queryset())
- queryset = queryset.filter(user=request.user)
- serializer = self.get_serializer(queryset, many=True)
- return Response(serializer.data)
-
-
- # perssion
- from rest_framework import permissions
- class CollectPermissions(permissions.BasePermission):
- """
- Custom permission to only allow owners of an object to edit it.
- """
- def has_object_permission(self, request, view, obj):
- # 判断是否是管理员
- if request.user.is_superuser:
- return True
- # 判断当前的用户对象和登录的用户对象是否是同一个,防止越权
- return obj == request.user
-
- # url
- # 收藏商品
- path('collect/', CollectView.as_view({"post":'create','get':'list'})),
- # 取消收藏
- path('collect/del/
/' , CollectView.as_view({"delete":'destroy'})),
商品购物车的接口实现: 购物车添加数量、修改商品购物车状态、加购商品
- # serializer
- from rest_framework import serializers
- from apps.cart.models import Cart
- from apps.goods.serializers import GoodsSerializer
-
- class CartSerializer(serializers.ModelSerializer):
- """用户的模型序列化器-写入"""
- class Meta:
- model = Cart
- fields = '__all__'
-
- class ReadInfoSerializer(serializers.ModelSerializer):
- """用户的模型序列化器-读取"""
- goods =GoodsSerializer()
- class Meta:
- model = Cart
- fields = '__all__'
-
-
- # view
- from rest_framework import status
- from rest_framework.response import Response
- from rest_framework.viewsets import GenericViewSet,mixins
- from .models import Cart
- from .serializers import CartSerializer, ReadInfoSerializer
-
-
- # Create your views here.
-
- class CartViecw(GenericViewSet,
- mixins.CreateModelMixin,
- mixins.UpdateModelMixin,
- mixins.DestroyModelMixin,
- mixins.ListModelMixin):
- queryset = Cart.objects.all()
- serializer_class = CartSerializer
-
- def get_serializer_class(self):
- # 实现读写操作使用不同的序列化器
- if self.action == 'list':
- return ReadInfoSerializer
- else:
- return self.serializer_class
-
- def create(self, request, *args, **kwargs):
- user = request.user
- goods =request.data.get('goods')
- if Cart.objects.filter(user=user,goods=goods):
- # 该商品存在
- cart_goods = Cart.objects.get(user=user,goods=goods)
- cart_goods.number +=1
- cart_goods.save()
- # 商品序列化
- serializer = self.get_serializer(cart_goods)
- return Response(serializer.data,status=status.HTTP_201_CREATED)
- else:
- # 没有该商品则进行添加该商品
- request.data['user'] = user.id
- return super().create(request,*args,**kwargs)
-
- def list(self, request, *args, **kwargs):
- query =self.get_queryset().filter(user=request.user)
- serializer = self.get_serializer(query, many=True)
- return Response(serializer.data)
-
- def update_goods_status(self,request, *args, **kwargs):
- obj =self.get_object()
- obj.is_checked = not obj.is_checked
- obj.save()
- return Response({"message":'修改成功'},status=status.HTTP_200_OK)
- def update_goods_number(self,request, *args, **kwargs):
- number = request.data.get('number')
- obj = self.get_object()
- if not isinstance(number,int): return Response({'error':'参数number只可为INT类型'})
- if number > obj.goods.stock:
- return Response({"message": "数量不可超过该商品的库存数量"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
- elif number <= 0:
- obj.delete()
- return Response({"message":"修改成功,已删除"},status=status.HTTP_200_OK)
- else:
- obj.number = number
- obj.save()
- return Response({"message": "修改成功"}, status=status.HTTP_200_OK)
-
- # url
- from apps.cart.views import CartViecw
- urlpatterns = [
- # 商品首页
- path('cart/', CartViecw.as_view({"post":'create','get':'list'})),
- # 修改商品购物车的状态
- path('cart/
/checked/' , CartViecw.as_view({"put":'update_goods_status'})), - # 修改商品数量
- path('cart/
/number/' , CartViecw.as_view({"put": 'update_goods_number'})), -
- ]
-
-
-
-
以上是django restframework商城的后端实现。