订单模块
一、订单模块
1、创 order应用

2、注册

3、拷贝子路由

4、主路由分发

5、models设计

6、views
from rest_framework.viewsets import GenericViewSet,ViewSet from rest_framework.mixins import CreateModelMixin from .import models,serializers from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response # 支付视图类 class PayViewSet(GenericViewSet,CreateModelMixin): permission_classes = [IsAuthenticated] # 认证组件 queryset = models.Order.objects.all() # 取出订单表中的所有queryset对象 serializer_class = serializers.PaySerializer # 序列化 类
# 重写create方法,返回pay_url。要知道serializer,因为pay_url在serializer对象中
def create(self,request,*args,**kwargs):
# response = super().create(request,*args,**kwargs) # 这样不行,拿不到serializer对象
serializer = self.get_serializer(data=request.data,context={'request':request})
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
return Response(serializer.context['pay_url'])
# 支付成功(支付回调)视图类 class SuccessViewSet(ViewSet): authentication_classes = () permission_classes = () # 支付宝同步回调给前台,在同步通知给后台处理 def get(self,request,*args,**kwargs): pass # 支付宝异步回调给后台 def post(self,request,*args,**kwargs): pass
7、serializers
from rest_framework import serializers from . import models from course.models import Course from rest_framework.exceptions import ValidationError from django.conf import settings print('123') class PaySerializer(serializers.ModelSerializer): # 要支持单购物和群购物(购物车),前台要提交 课程主键(们) courses = serializers.PrimaryKeyRelatedField(queryset=Course.objects.all(), write_only=True, many=True) print('课程课程',courses) class Meta: model = models.Order fields = ('subject', 'total_amount', 'pay_type', 'courses') extra_kwargs = { 'total_amount': { 'required': True }, 'pay_type': { 'required': True }, } # 订单总结校验 def _check_total_amount(self, attrs): print(attrs) courses = attrs.get('courses') total_amount = attrs.get('total_amount') total_price = 0 for course in courses: total_price += course.price if total_price != total_amount: raise ValidationError('total_amount error') return total_amount # 生成订单号 def _get_out_trade_no(self): import uuid code = '%s' % uuid.uuid4() return code.replace('-', '') # 获取支付人 def _get_user(self): return self.context.get('request').user # 获取支付链接 def _get_pay_url(self, out_trade_no, total_amount, subject): from libs import ipay order_string = ipay.alipay.api_alipay_trade_page_pay( out_trade_no=out_trade_no, total_amount=float(total_amount), # 只有生成支付宝链接时,不能用Decimal subject=subject, return_url=settings.RETURN_URL, notify_url=settings.NOTIFY_URL, ) pay_url = ipay.gateway + '?' + order_string print("支付支付支付支付",pay_url) # 将支付链接存入,传递给views self.context['pay_url'] = pay_url # 入库(两个表)的信息准备 def _before_create(self, attrs, user, out_trade_no): attrs['user'] = user attrs['out_trade_no'] = out_trade_no def validate(self, attrs): # 1)订单总价校验 total_amount = self._check_total_amount(attrs) # 2)生成订单号 out_trade_no = self._get_out_trade_no() # 3)支付用户:request.user user = self._get_user() # 4)支付链接生成 subject是前端传过来 self._get_pay_url(out_trade_no, total_amount, attrs.get('subject')) # 5)入库(两个表)的信息准备 self._before_create(attrs, user, out_trade_no) # 代表该校验方法通过,进入入库操作 return attrs # 重写入库方法的目的:完成订单与订单详情两个表入库操作 def create(self, validated_data): courses = validated_data.pop('courses') # 订单表入库,不需要courses order = models.Order.objects.create(**validated_data) # 订单详情表入库:只需要订单对象,课程对象(courses要拆成一个个course) for course in courses: models.OrderDetail.objects.create(order=order, course=course, price=course.price, real_price=course.price) # 先循环制造数据列表[{}, ..., {}],用群增完成入库 bulk_create(),效率高 return order


导包问题解决:

。

浙公网安备 33010602011771号