专题:Vue+Django REST framework前后端分离生鲜电商
Vue+Django REST framework 打造前后端分离的生鲜电商项目(慕课网视频)。
Github地址:https://github.com/xyliurui/DjangoOnlineFreshSupermarket ;
Django版本:2.2、djangorestframework:3.9.2。
前端Vue模板可以直接联系我拿。
更多内容请点击 我的博客 查看,欢迎来访。
修改Vue指向线上地址
由于需要调试支付宝的相关功能,将Vue项目指向线上的接口,修改 src/api/api.js 中的local_host
//let local_host = 'http://localhost:8000';
let local_host = 'http://xx.ip.ip.xx:8000';
然后记得启动Django的线上服务,而不是运行在本地了,重启Vue服务器,再访问 http://127.0.0.1:8080 看下是否能够正常加载接口的数据。
用户在购物车中点击去结算,会进入OrderInfoViewSet
逻辑,就会创建一个订单,然后将当前用户购物车中的商品取出来,放在该订单对应的商品列表中。
OrderInfoSerializer序列化时生成支付url
在官方文档 https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield 中有一个字段是SerializerMethodField
,
这是一个只读字段。它通过序列化类中的方法,来获取其值。它可以用来向对象的序列化表示添加任何类型的数据。
序列化器方法应该接受单个参数(除了self
),该参数obj
是被序列化的对象。它应该返回想要包含在对象序列化表示中的任何内容。
修改 apps/trade/serializers.py ,在OrderInfoSerializer
添加一个alipay_url
字段
from utils.alipay import AliPay, get_server_ip
from DjangoOnlineFreshSupermarket.settings import app_id, alipay_debug, alipay_public_key_path, app_private_key_path
class OrderInfoSerializer(serializers.ModelSerializer):
user = serializers.HiddenField(
default=serializers.CurrentUserDefault() # 表示user为隐藏字段,默认为获取当前登录用户
)
order_sn = serializers.CharField(read_only=True) # 只能读,不能显示给用户修改,只能后台去修改
trade_no = serializers.CharField(read_only=True) # 只读
pay_status = serializers.CharField(read_only=True) # 只读
pay_time = serializers.DateTimeField(read_only=True) # 只读
alipay_url = serializers.SerializerMethodField() # 生成支付宝url
def generate_order_sn(self):
# 当前时间+userid+随机数
import time
from random import randint
order_sn = '{time_str}{user_id}{random_str}'.format(time_str=time.strftime('%Y%m%d%H%M%S'), user_id=self.context['request'].user.id, random_str=randint(10, 99))
return order_sn
def validate(self, attrs):
# 数据验证成功后,生成一个订单号
attrs['order_sn'] = self.generate_order_sn()
return attrs
def get_alipay_url(self, obj):
# 方法命名规则为:get_<field_name>
server_ip = get_server_ip()
alipay = AliPay(
app_id=app_id, # 自己支付宝沙箱 APP ID
notify_url="http://{}:8000/alipay/return/".format(server_ip),
app_private_key_path=app_private_key_path, # 可以使用相对路径那个
alipay_public_key_path=alipay_public_key_path, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
debug=alipay_debug, # 默认False,
return_url="http://{}:8000/alipay/return/".format(server_ip)
)
# 创建订单
order_sn = obj.order_sn
order_amount = obj.order_amount
url = alipay.direct_pay(
subject="生鲜超市-{}".format(order_sn),
out_trade_no=order_sn,
total_amount=order_amount,
# return_url="http://{}:8000/alipay/return/".format(server_ip) # 支付完成后自动跳回该url,可以不填了,因为初始化已经加上了
)
re_url = "https://openapi.alipaydev.com/gateway.do?{data}".format(data=url)
return re_url
class Meta:
model = OrderInfo
fields = "__all__"
该字段用于订单创建时,生成支付宝的支付url
在 alipay.py 文件中
if return_url is None:
data["notify_url"] = self.notify_url
data["return_url"] = self.return_url
没有指定return_url
时,直接使用初始化的return_url
修改完成后把代码上传到服务器,每次修改代码后都需要Upload to服务器,避免出错,然后重启Debug
接下来访问 http://xx.ip.ip.xx:8000/ 看API是否正常
接下来访问 http://xx.ip.ip.xx:8000/orderinfo/ 测试创建新订单
POST完成后,可以看到返回的值
可以拿到alipay_ur