订单模块

一、订单模块

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

 

 

 导包问题解决:

posted @ 2020-03-15 22:34  薛定谔的猫66  阅读(538)  评论(0)    收藏  举报