Django REST:get_queryset提供重复的响应

时间:2019-03-06 04:50:25

标签: python django django-rest-framework

我正在创建一个简单的在线商店应用程序,因此当您要购买商品时,单击按钮即可将您带到收费api。 (例如,第2项将定向到/ api / charge / 2)

urls.py

from django.urls import path
from gallery.views import ClothingView
from gallery.api.views import ListClothes
from gallery.api.views import ChargeView

urlpatterns = [
    path('api/<int:num>/', ListClothes.as_view()),
    path('api/charge/<int:num>', ChargeView.as_view(), name='charge_api'),
]

views.py

class ChargeView(ListCreateAPIView):
    serializer_class = ChargeSerializer
    count = 0

    def get_queryset(self):
        a = ClothingModel.objects.filter(id=self.kwargs['num']).first()
        net_price = int(float(a.full_price) * 100)
        if float(a.discount) > 0.00:
            net_price = int(net_price * (1 - (float(a.discount) / 100)))

        self.count += 1

        print(self.count)

        if self.count == 1:

            stripe.api_key = settings.API_KEY
            charge_rtn_body = stripe.Charge.create(    # Create charge object
                amount=net_price,
                currency="usd",
                source="tok_visa", # obtained with Stripe.js
                description= "[Stripe charge] " + a.description.upper()
            )

        return ClothingModel.objects.filter(id=self.kwargs['num'])

serializers.py

class ChargeSerializer(serializers.ModelSerializer):
    class Meta:
        model = ClothingModel
        fields = ('full_price', 'discount', 'description')

每次调用api时,我都会为Stripe(收费方法)创建一个收费对象,但取决于服装商品ID。因此,为了解决这个问题,我在get_queryset()上使用self.kwargs链接到服装。一次单击后,当我在Stripe仪表板上查看费用时,一次产生多个费用(一次4个)。我已经将if self.count == 1:硬编码为一种变通方法,但是知道这不是一个好习惯。是否有每个单独请求在get_queryset()中进行这些多次调用的原因,我该如何干净地实现?谢谢。

2 个答案:

答案 0 :(得分:0)

仅应在POST请求中创建对象。每次调用视图时都会调用get_queryset(即使是GET请求)。因此,应将创建的对象移动到view函数中。 URL的动态部分可从此处显示的视图函数中访问-https://docs.djangoproject.com/en/2.1/topics/http/urls/#example

class ChargeView(ListCreateAPIView):

    def post(self, request, num):
        charge = ClothingModel.objects.get(id=num)

答案 1 :(得分:0)

from django.conf import settings # new
from django.views.generic.base import TemplateView
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY

class HomePageView(TemplateView):
    template_name = 'stripe.html'

    def get_context_data(self, **kwargs): # new
        context = super().get_context_data(**kwargs)
        context['key'] = settings.STRIPE_PUBLISHABLE_KEY
        return context

def charge(request): # new
    if request.method == 'POST':
        charge = stripe.Charge.create(amount=5000,currency='ind',description='A Django charge',
            source=request.POST['stripeToken'])
        return render(request, 'charge.html')