• django rest framework 学习笔记-实战商城3


     01用户模块模型定义_哔哩哔哩_bilibili  本博客借鉴至大佬的视频学习笔记

    用户模块及商品数据表结构设计

    1. from ckeditor.fields import RichTextField # pip install django-ckeditor
    2. from django.db import models
    3. # Create your models here.
    4. # from wx.richtext import RichTextField
    5. from common.db import BaseModel
    6. class GoodsGroup(BaseModel):
    7. """商品分类"""
    8. name = models.CharField(verbose_name="分类名称", help_text="分类名称", max_length=15,blank=True,null=True)
    9. image = models.CharField(verbose_name="图片链接", help_text="图片链接", max_length=200, blank=True, null=True)
    10. status = models.BooleanField(verbose_name="是否启用", help_text="是否启用", default=False,blank=True,null=True)
    11. class Meta:
    12. db_table = 'goods_group'
    13. verbose_name = "商品分类表"
    14. verbose_name_plural = verbose_name
    15. def __str__(self):
    16. return self.name
    17. class Goods(BaseModel):
    18. """商品"""
    19. group = models.ForeignKey('GoodsGroup', verbose_name="分类", help_text="分类", max_length=15, on_delete=models.CASCADE)
    20. image = models.CharField(verbose_name="图片链接", help_text="图片链接", max_length=200, blank=True, null=True)
    21. title = models.CharField(verbose_name="标题", help_text="标题", max_length=20, blank=True,null=True)
    22. desc = models.CharField(verbose_name="商品描述", help_text="商品描述", max_length=200, blank=True,null=True)
    23. price = models.DecimalField(verbose_name="商品价格", help_text="商品价格", max_digits=10, decimal_places=2, blank=True,null=True)
    24. cover = models.ImageField(verbose_name="封面图链接", help_text="封面图链接", max_length=200, blank=True,null=True)
    25. stock = models.IntegerField(verbose_name="库存", help_text="库存", blank=True, null=True, default=1)
    26. sales = models.IntegerField(verbose_name="销量", help_text="销量", blank=True, null=True, default=0)
    27. is_on = models.BooleanField(verbose_name="是否上架", help_text="是否上架", blank=True, null=True, default=False)
    28. recommend = models.BooleanField(verbose_name="是否推荐", help_text="是否推荐", blank=True, null=True, default=False)
    29. class Meta:
    30. db_table = 'goods'
    31. verbose_name = '商品表'
    32. verbose_name_plural = verbose_name
    33. def __str__(self):
    34. return self.title
    35. class Detail(BaseModel):
    36. """商品详情"""
    37. goods = models.OneToOneField('Goods', verbose_name="商品", on_delete=models.CASCADE, max_length=200)
    38. producer = models.CharField(verbose_name='厂商', help_text='厂商', max_length=200, blank=True,null=True)
    39. norms = models.CharField(verbose_name='规格', help_text='规格', max_length=200, blank=True,null=True)
    40. details = RichTextField(verbose_name='商品详情', help_text='商品详情', max_length=200,blank=True,null=True)
    41. class Meta:
    42. db_table = 'details'
    43. verbose_name = '详情'
    44. verbose_name_plural = verbose_name
    45. def __str__(self):
    46. return self.goods
    47. class GoodsBanner(BaseModel):
    48. """商品轮播图"""
    49. title = models.CharField(verbose_name='轮播图名称', help_text='轮播图名称', max_length=20, blank=True)
    50. image = models.ImageField(verbose_name='轮播图链接', help_text='轮播图链接', max_length=200, blank=True)
    51. # url = models.CharField(verbose_name='跳转的地址',help_text='跳转的地址',max_length=200,blank=True)
    52. status = models.BooleanField(verbose_name='是否启用', help_text='是否启用', default=False,blank=True,null=True)
    53. seq = models.IntegerField(verbose_name='顺序', help_text='顺序', default=1, blank=True,null=True)
    54. class Meta:
    55. db_table = 'banner'
    56. verbose_name = '首页商品轮播'
    57. verbose_name_plural = verbose_name
    58. def __str__(self):
    59. return self.title
    60. class Collect(models.Model):
    61. """商品收藏"""
    62. user = models.ForeignKey('users.User', help_text='用户ID', verbose_name='用户ID', on_delete=models.CASCADE,blank=True,null=True)
    63. goods = models.ForeignKey('goods.Goods', help_text="商品ID", verbose_name="商品ID", on_delete=models.CASCADE,blank=True,null=True)
    64. class Meta:
    65. db_table = 'collect'
    66. verbose_name = "收藏商品"
    67. verbose_name_plural = verbose_name
    68. def __str__(self):
    69. return self.goods

    Django自带admin配置

    1. from django.contrib import admin
    2. from .models import GoodsGroup,Goods,Detail,GoodsBanner,Collect
    3. # Register your models here.
    4. @admin.register(GoodsGroup)
    5. class GoodsGroupAdmin(admin.ModelAdmin):
    6. list_display = ['name','status']
    7. @admin.register(Goods)
    8. class GoodsAdmin(admin.ModelAdmin):
    9. list_display = ['title','group','price','stock','sales','is_on']
    10. @admin.register(Detail)
    11. class DetailGroupAdmin(admin.ModelAdmin):
    12. list_display = ['goods', 'producer','norms']
    13. @admin.register(GoodsBanner)
    14. class GoodsBannerAdmin(admin.ModelAdmin):
    15. list_display = ['title', 'status']
    16. @admin.register(Collect)
    17. class CollectAdmin(admin.ModelAdmin):
    18. list_display = ['user', 'goods']

    商品首页接口实现

    1. class IndexView(APIView):
    2. """首页数据展示"""
    3. def get(self,request):
    4. """返回轮播图、商品分类"""
    5. group = GoodsGroup.objects.filter(status=True)
    6. groupSer =GoodsGroupSerializer(group,many=True)
    7. # 轮播图
    8. banner = GoodsBanner.objects.filter(status=True)
    9. bannerSer = GoodsBannerSerializer(banner,many=True)
    10. # 推荐的商品
    11. goods = Goods.objects.filter(recommend=True)
    12. goodsSer = GoodsSerializer(goods,many=True)
    13. # 返回数据
    14. result = {
    15. 'banner': bannerSer.data,
    16. 'goods':goodsSer.data,
    17. 'group':groupSer.data
    18. }
    19. return Response({"message":'ok','data':result},status=status.HTTP_200_OK)
    20. # 商品首页
    21. path('index/', IndexView.as_view()),

    商品列表获取和分类排序接口

    1. # view
    2. class GoodsView(ReadOnlyModelViewSet):
    3. """"商品列表接口"""
    4. serializer_class = GoodsSerializer
    5. # 选择上架的商品
    6. queryset = Goods.objects.filter(is_on=True),
    7. # 实现商品分类和推荐类过滤
    8. filterset_fields = ('group','recommend')
    9. # 通过价格和销量排序
    10. ordering_fields =('sales','price','create_time')
    11. # url
    12. # 商品列表接口
    13. path('goods/', GoodsView.as_view({"get":'list'})),
    14. # 单个商品获取
    15. path('goods//', GoodsView.as_view({"get":'retrieve'})),
    16. # setting
    17. # 过滤器信息配置、排序器配置
    18. 'DEFAULT_FILTER_BACKENDS':['django_filters.rest_framework.DjangoFilterBackend',
    19. 'rest_framework.filters.OrderingFilter']
    20. # 注册
    21. 'django_filters',

    商品的收藏与取消收藏接口

    1. # view
    2. class CollectView(mixins.RetrieveModelMixin,
    3. mixins.CreateModelMixin
    4. ,mixins.ListModelMixin,mixins.DestroyModelMixin,GenericViewSet):
    5. """
    6. 商品收藏与取消
    7. create: 收藏
    8. delete: 取消
    9. list: 收藏列表
    10. """
    11. queryset = Collect.objects.all()
    12. serializer_class = CollectSerializer
    13. permission_classes = [IsAuthenticated,CollectPermissions]
    14. filterset_fields = ("user",)
    15. def create(self, request, *args, **kwargs):
    16. # 获取请求参数
    17. user = request.user
    18. params_user_id = request.data.get('user')
    19. # 检验请求参数中的id是否当前登录的用户ID
    20. if user.id != params_user_id:
    21. return Response({'error':'你没有用户权限访问该信息'},status=status.HTTP_400_BAD_REQUEST)
    22. return super().create(request, *args, **kwargs)
    23. def list(self, request, *args, **kwargs):
    24. """商品收藏列表"""
    25. queryset = self.filter_queryset(self.get_queryset())
    26. queryset = queryset.filter(user=request.user)
    27. serializer = self.get_serializer(queryset, many=True)
    28. return Response(serializer.data)
    29. # perssion
    30. from rest_framework import permissions
    31. class CollectPermissions(permissions.BasePermission):
    32. """
    33. Custom permission to only allow owners of an object to edit it.
    34. """
    35. def has_object_permission(self, request, view, obj):
    36. # 判断是否是管理员
    37. if request.user.is_superuser:
    38. return True
    39. # 判断当前的用户对象和登录的用户对象是否是同一个,防止越权
    40. return obj == request.user
    41. # url
    42. # 收藏商品
    43. path('collect/', CollectView.as_view({"post":'create','get':'list'})),
    44. # 取消收藏
    45. path('collect/del//', CollectView.as_view({"delete":'destroy'})),

    商品购物车的接口实现: 购物车添加数量、修改商品购物车状态、加购商品

    1. # serializer
    2. from rest_framework import serializers
    3. from apps.cart.models import Cart
    4. from apps.goods.serializers import GoodsSerializer
    5. class CartSerializer(serializers.ModelSerializer):
    6. """用户的模型序列化器-写入"""
    7. class Meta:
    8. model = Cart
    9. fields = '__all__'
    10. class ReadInfoSerializer(serializers.ModelSerializer):
    11. """用户的模型序列化器-读取"""
    12. goods =GoodsSerializer()
    13. class Meta:
    14. model = Cart
    15. fields = '__all__'
    16. # view
    17. from rest_framework import status
    18. from rest_framework.response import Response
    19. from rest_framework.viewsets import GenericViewSet,mixins
    20. from .models import Cart
    21. from .serializers import CartSerializer, ReadInfoSerializer
    22. # Create your views here.
    23. class CartViecw(GenericViewSet,
    24. mixins.CreateModelMixin,
    25. mixins.UpdateModelMixin,
    26. mixins.DestroyModelMixin,
    27. mixins.ListModelMixin):
    28. queryset = Cart.objects.all()
    29. serializer_class = CartSerializer
    30. def get_serializer_class(self):
    31. # 实现读写操作使用不同的序列化器
    32. if self.action == 'list':
    33. return ReadInfoSerializer
    34. else:
    35. return self.serializer_class
    36. def create(self, request, *args, **kwargs):
    37. user = request.user
    38. goods =request.data.get('goods')
    39. if Cart.objects.filter(user=user,goods=goods):
    40. # 该商品存在
    41. cart_goods = Cart.objects.get(user=user,goods=goods)
    42. cart_goods.number +=1
    43. cart_goods.save()
    44. # 商品序列化
    45. serializer = self.get_serializer(cart_goods)
    46. return Response(serializer.data,status=status.HTTP_201_CREATED)
    47. else:
    48. # 没有该商品则进行添加该商品
    49. request.data['user'] = user.id
    50. return super().create(request,*args,**kwargs)
    51. def list(self, request, *args, **kwargs):
    52. query =self.get_queryset().filter(user=request.user)
    53. serializer = self.get_serializer(query, many=True)
    54. return Response(serializer.data)
    55. def update_goods_status(self,request, *args, **kwargs):
    56. obj =self.get_object()
    57. obj.is_checked = not obj.is_checked
    58. obj.save()
    59. return Response({"message":'修改成功'},status=status.HTTP_200_OK)
    60. def update_goods_number(self,request, *args, **kwargs):
    61. number = request.data.get('number')
    62. obj = self.get_object()
    63. if not isinstance(number,int): return Response({'error':'参数number只可为INT类型'})
    64. if number > obj.goods.stock:
    65. return Response({"message": "数量不可超过该商品的库存数量"}, status=status.HTTP_422_UNPROCESSABLE_ENTITY)
    66. elif number <= 0:
    67. obj.delete()
    68. return Response({"message":"修改成功,已删除"},status=status.HTTP_200_OK)
    69. else:
    70. obj.number = number
    71. obj.save()
    72. return Response({"message": "修改成功"}, status=status.HTTP_200_OK)
    73. # url
    74. from apps.cart.views import CartViecw
    75. urlpatterns = [
    76. # 商品首页
    77. path('cart/', CartViecw.as_view({"post":'create','get':'list'})),
    78. # 修改商品购物车的状态
    79. path('cart//checked/', CartViecw.as_view({"put":'update_goods_status'})),
    80. # 修改商品数量
    81. path('cart//number/', CartViecw.as_view({"put": 'update_goods_number'})),
    82. ]

    以上是django restframework商城的后端实现。

  • 相关阅读:
    Python界面编辑器Tkinter布局助手 使用体验
    Web基础与HTTP协议
    [SDX35+WCN6856]SDX35 + WCN6856 WiFi导致系统crash问题分析及解决方案
    shell之df和du命令介绍
    asp.net基于net的冰淇淋订单管理系统-计算机毕业设计
    matlab查找符号表达式中的符号变量
    Practical+Reverse+Engineering第三章List习题
    LRU 缓存
    人脸检测-级联卷积
    C语言学习:3、数据输入
  • 原文地址:https://blog.csdn.net/qq_44238024/article/details/136244623