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

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/<int:pk>/', 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/<int:pk>/', 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/<int:pk>/checked/', CartViecw.as_view({"put":'update_goods_status'})),
    # 修改商品数量
    path('cart/<int:pk>/number/', CartViecw.as_view({"put": 'update_goods_number'})),

]

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

相关推荐
Zhao-Jichao1 小时前
AI Prompting for Everyone 课程笔记 - P21 总结 Conclusion
人工智能·笔记
欢欢李2 小时前
【LTE L3 笔记 05】LTE同步信号
笔记·无线通信·物理层·lte·空口协议
La Pulga3 小时前
【FreeRTOS源码学习笔记】空闲任务与阻塞延时
笔记·mcu·学习·嵌入式·freertos·实时操作系统
蒸蒸yyyyzwd3 小时前
秋招学习笔记 day106
笔记·学习
小李不想当小白4 小时前
WDG看门狗(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
欢欢李5 小时前
【LTE L3 笔记 04】LTE帧结构
笔记·无线通信·物理层·lte·空口协议
Zhao-Jichao7 小时前
AI Prompting for Everyone 课程笔记 - P20 实验与期末项目 Lab and Final Project
前端·人工智能·笔记
lisw058 小时前
作为人类代理的大语言模型及其角色分类!
人工智能·学习·语言模型
Z21-X8 小时前
云原生运维实战笔记:企业网站综合上云部署与云运维服务全景解析
运维·笔记·学习·云原生
坤坤子吖8 小时前
Linux网络编程:UDP进阶,从字典服务器到简单聊天室
linux·服务器·网络·c++·笔记·学习