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商城的后端实现。

相关推荐
AI算法工程师Moxi3 小时前
什么时候可以开始学习深度学习?
人工智能·深度学习·学习
jiedaodezhuti4 小时前
ElasticSearch重启之后shard未分配问题的解决
笔记·elasticsearch
z人间防沉迷k5 小时前
堆(Heap)
开发语言·数据结构·笔记·python·算法
z542968z5 小时前
Springboot3自定义starter笔记
笔记
丰锋ff6 小时前
操作系统学习笔记第3章 内存管理(灰灰题库)
笔记·学习
jackson凌7 小时前
【Java学习笔记】equals方法
java·笔记·学习
虾球xz7 小时前
游戏引擎学习第282天:Z轴移动与摄像机运动
c++·学习·游戏引擎
.小墨迹7 小时前
Apollo学习——planning模块(3)之planning_base
linux·开发语言·c++·学习·自动驾驶
龙湾开发7 小时前
计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 10.增强表面细节(一)过程式凹凸贴图
c++·笔记·学习·3d·图形渲染
wxin_VXbishe7 小时前
springboot旅游小程序-计算机毕业设计源码76696
java·spring boot·python·spring·django·sqlite·flask