我正在使用付款处理程序Stripe在我的DRF结构中与哲学问题作斗争。我正在通过我的DRF REST API销售具有django模型Product
的产品。我想知道我是否应该创建Product
,然后在我的create
视图中处理付款,如下所示:
class ProductViewSet(viewsets.ModelViewSet):
...
def create(self, request):
serializer = ProductSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
product = serializer.save()
try:
response = stripe.Charge.create(
amount=product.cost,
currency="usd",
source=request.data["token"], # Done with Stripe.js
description="Product"
)
product.charge_id = response.charge_id
...
或者相反,如果我处理Product
的序列化中的付款:
class ProductSerializer(serializers.Serializer):
...
def create(self, validated_data):
product = Product.objects.create(**validated_data)
# Will raise an Excetpion and stop the creation:
response = stripe.Charge.create(
amount=product.cost,
currency="usd",
source=validated_data["token"], # Done with Stripe.js
description="Product"
)
return product
哪一种更好的做法?或者,我是否完全忽略了这一点,应该采用不同的方式吗?
其次,有没有办法在create
路由的Browsable API模板中嵌入Stripe.js和所需的表单,这样我就可以在不需要任何前端的情况下测试我的REST了?
感谢您的帮助
答案 0 :(得分:1)
在我看来,正确的方法是两种提供的方法的混合,因为您应该在Stripe
类中发送ModelViewSet
请求,但仅在服务后保存Product
实体&# 39;成功的回应。
否则,如果服务的响应不成功,我会回滚每个数据库操作(使用Django 1.6+,你可以使用transaction.atomic()
记录的here来完成。
我不喜欢你的第二种方法,因为根据DRF关于create
serializers.Serializer
方法的文档,这个方法应该只返回给定验证数据的新实体实例,所以我会不添加其他业务逻辑。
关于第二个问题,我将构造create
方法以使用注入的模拟对象来处理Stripe
请求,这样您就可以测试关于任何前端交互的代码(显然这样你不进行集成测试,而是进行单元测试。