【问题标题】:Getting AttributeError in Django在 Django 中获取 AttributeError
【发布时间】:2020-04-19 20:40:37
【问题描述】:

我正在使用 Stripe 在我的 Django 应用中处理付款。 每当我尝试填写虚拟卡凭据并提交时,都会出现以下错误。

AttributeError, 'Payment' 对象没有属性 'save'

我不知道如何将付款对象保存在“views.py”中。

我已成功在我的应用中应用迁移并已迁移它,但我仍然收到此错误。

以下是我的观点.py

from django.conf import settings
from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView, View
from django.utils import timezone
from django.shortcuts import redirect
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
import stripe 

from django.contrib import messages
# token = stripe.api_key
stripe.api_key = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
# `source` is obtained with Stripe.js; see https://stripe.com/docs/payments/accept-a-payment-charges#web-create-token
# stripe.api_key = settings.STRIPE_SECRET_KEY
# Create your views here.

from .models import Item, OrderItem, Order, BillingInformation, Payment
from .forms import CheckoutForm
# def home(request):
#     context = {
#         'items': Item.objects.all()
#     }

#     return render(request,'home.html',context)

class HomeView(ListView):
    model = Item

    template_name = 'home.html'

class ItemDetails(DetailView):
    model = Item
    template_name = 'product.html'

@login_required
def add_to_cart(request, slug):
    item = get_object_or_404(Item, slug=slug)
    order_item, created = OrderItem.objects.get_or_create(
        order_item=item,
        user=request.user,
        is_ordered=False
        )
    order_qs = Order.objects.filter(user=request.user, is_ordered=False)
    if order_qs.exists():
        order = order_qs[0]
        print(order)
        if order.order_items.filter(order_item__slug=item.slug).exists():
            order_item.item_quantity += 1
            order_item.save()
        else:
                order.order_items.add(order_item)

    else:
            date_of_order = timezone.now()
            order = Order.objects.create(user=request.user,date_of_order= date_of_order)
            order.order_items.add(order_item)
    return redirect("core:order-summary")

@login_required
def remove_from_cart(request, slug):
    item = get_object_or_404(Item,slug=slug)
    order_qs = Order.objects.filter(user=request.user, is_ordered=False)
    if order_qs.exists():
        order = order_qs[0]
        if order.order_items.filter(order_item__slug=item.slug).exists():
            order_item = OrderItem.objects.filter(
                                order_item=item,
                                user=request.user,
                                is_ordered=False
                                )[0]
            order.order_items.filter(order_item__slug=item.slug).delete()
        else:
            return redirect("core:product",slug=slug)
    else:
        return redirect("core:product",slug=slug)

    return redirect("core:product",slug=slug)


@login_required
def remove_single_item_from_cart(request, slug):
    item = get_object_or_404(Item,slug=slug)
    order_qs = Order.objects.filter(user=request.user, is_ordered=False)
    if order_qs.exists():
        order = order_qs[0]
        if order.order_items.filter(order_item__slug=item.slug).exists():
            order_item = OrderItem.objects.filter(
                                order_item=item,
                                user=request.user,
                                is_ordered=False
                                )[0]
            if order_item.item_quantity > 1:
                order_item.item_quantity -= 1
                order_item.save()
            else:
                order.order_items.filter(order_item__slug=item.slug).delete()

        else:
            return redirect("core:order-summary")
    else:
        return redirect("core:order-summary")

    return redirect("core:order-summary")



class OrderSummary(LoginRequiredMixin,View):
    def get(self, *args, **kwargs):
        order = Order.objects.get(user=self.request.user, is_ordered=False)
        context = {'object':order}
        return render(self.request,'order-summary.html',context)



class CheckoutView(LoginRequiredMixin,View):


    def get(self,*args,**kwargs):

        form = CheckoutForm
        context = {'form':form}
        return render(self.request,'checkout.html',context)

    def post(self, *args, **kwargs):
        form = CheckoutForm(self.request.POST or None)
        order = Order.objects.get(user=self.request.user, is_ordered=False)
        if form.is_valid():
            street = form.cleaned_data.get('street')
            city = form.cleaned_data.get('city')
            state = form.cleaned_data.get('state')
            landmark = form.cleaned_data.get('landmark')
            shipping_same_as_billing = form.cleaned_data.get('shipping_same_as_billing')
            save_info = form.cleaned_data.get('save_info')
            payment_info = form.cleaned_data.get('payment_info')

            billing_address = BillingInformation(
                user = self.request.user,
                street = street,
                city = city,
                state = state,
                landmark = landmark,
                shipping_same_as_billing = shipping_same_as_billing,
                save_info = save_info,
                payment_info = payment_info
            )

            billing_address.save()
            order.billing_address = billing_address
            order.save()


        return redirect('core:order-summary')

class Payment(LoginRequiredMixin, View):

    def get(self,*args,**kwargs):
        order = Order.objects.get(user=self.request.user, is_ordered=False)
        context = {
            'order':order
        }
        return render(self.request,'payment.html',context)

    def post(self,*args,**kwargs):
        order = Order.objects.get(user=self.request.user,is_ordered=False)
            # token = self.request.POST.get('stripeToken')
        order_amount =  int(order.get_cart_total())
        try:
            charge = stripe.Charge.create(
                    amount=order_amount,
                    currency="inr",
                    source = self.request.POST.get('stripeToken')
                    )

            payment = Payment()
            payment.stripe_charge_id = charge['id']
            payment.amount = order_amount
            payment.user = self.request.user
            payment.save()

            order.is_ordered = True
            order.payment = payment

            order.save()
            messages.success(self.request,"YaYY!! Your order has been successfully placed")
            return render(self.request,'order_placed.html')
        except stripe.error.CardError as e:
            # Problem with the card
            messages.error(self.request,"Card error")
            return redirect("/")
            # pass
        except stripe.error.RateLimitError as e:
            # Too many requests made to the API too quickly

            messages.error(self.request,"Rate limit error")
            # pass
            return redirect("/")
        except stripe.error.InvalidRequestError as e:
            print(e)
            # Invalid parameters were supplied to Stripe API
            # pass

            messages.error(self.request,"Invalid request  error")
            return redirect("/")
        except stripe.error.AuthenticationError as e:
            # Authentication Error: Authentication with Stripe API failed (maybe you changed API keys recently)
            # pass

            messages.error(self.request,"Authentication error")
            return redirect("/")
        except stripe.error.APIConnectionError as e:
            # Network communication with Stripe failed
            # pass

            messages.error(self.request,"API connection error")
            return redirect("/")
        except stripe.error.StripeError as e:
            # Stripe Error
            # pass

            messages.error(self.request,"Stripe error")
            return redirect("/")

以下是我的models.py

from django.db import models
from django.conf import settings
from django.shortcuts import reverse
# Create your models here.

CATEGORY_CHOICES = (
        ('S','Shirt'),
        ('SW','Sports Wear'),
        ('OW','Out Wear'),
)

LABEL_CHOICES = (
        ('P','primary'),
        ('S','success'),
        ('D','danger'),
)

PAYMENT_METHOD = (
    ('S','Stripe'),
    ('P',"PayPal"),
)


class Item(models.Model):
    item_name = models.CharField(max_length=200)
    item_price = models.FloatField()
    item_discounted_price = models.FloatField(null=True,blank=True)
    item_description = models.TextField()
    item_category = models.CharField(choices=CATEGORY_CHOICES, default='S', max_length=2)
    item_label = models.CharField(choices=LABEL_CHOICES, default='P', max_length=1)
    item_discount = models.PositiveIntegerField(null=True,blank=True)
    item_image = models.CharField(max_length=500,default='http://leeford.in/wp-content/uploads/2017/09/image-not-found.jpg')
    slug = models.SlugField(default='test-product')


    class Meta:
        db_table = 'Item'

    def __str__(self):
        return self.item_name

    def get_absolute_url(self):
        return reverse('core:product', kwargs={
                    'slug':self.slug
        })

    def get_add_to_cart_url(self):
           return reverse('core:add-to-cart', kwargs={
                    'slug':self.slug
        })

    def get_remove_from_cart_url(self):
        return reverse('core:remove-from-cart', kwargs={
                    'slug':self.slug
        })

    def get_item_price(self):
        if self.item_discounted_price:
            return self.item_discounted_price
        else:
            return self.item_price


class OrderItem(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.CASCADE, blank=True, null=True)
    order_item = models.ForeignKey(Item, on_delete = models.CASCADE)
    item_quantity = models.PositiveIntegerField(default=1)
    is_ordered = models.BooleanField(default=False)

    class Meta:
        db_table = 'Order Item'

    def __str__(self):
        return str(self.item_quantity) + " " + self.order_item.item_name

    def get_total_item_price(self):
        return  self.item_quantity * self.order_item.get_item_price()

    def get_total_savings(self):
        if self.order_item.item_discounted_price:
            return (self.order_item.item_price - self.order_item.item_discounted_price)*self.item_quantity
        else:
            return 0

class BillingInformation(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete = models.CASCADE)
    street = models.CharField(max_length=300)
    city = models.CharField(max_length=50)
    pin_code = models.CharField(max_length=6)
    state = models.CharField(max_length=100)
    landmark = models.CharField(max_length=500)
    shipping_same_as_billing = models.BooleanField(default=False)
    save_info = models.BooleanField(default=False)
    payment_info = models.CharField(choices=PAYMENT_METHOD,max_length=1)

    def __str__(self):
        return self.street+ " " + self.city+ " " + self.state


class Payment(models.Model):
    stripe_charge_id = models.CharField(max_length=50)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,blank=True, null=True)
    amount = models.FloatField(default=0)
    time_stamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.user.username



class Order(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.CASCADE)
    order_items = models.ManyToManyField(OrderItem)
    date_of_order = models.DateTimeField()
    is_ordered = models.BooleanField(default=False)
    billing_address = models.ForeignKey(BillingInformation,on_delete=models.PROTECT,blank=True,null=True)
    payment = models.ForeignKey(Payment,on_delete=models.SET_NULL,null=True)

    class Meta:
        db_table = 'Order'

    def __str__(self):
        return self.user.username

    def get_cart_total(self):
        price = 0
        for i in self.order_items.all():
            price += i.get_total_item_price()
        return price

以下是错误

 AttributeError at /payment/stripe/ 'Payment' object has no attribute 'save' 
 Request Method:    POST Request
 URL:   http://localhost:8000/payment/stripe/ 
 Django Version:    2.2.4
 Exception Type:    AttributeError Exception Value:  'Payment' object has no attribute 'save' 
 Exception Location:    C:\Users\hrshk\Desktop\ecomm\core\views.py in post, line 178

【问题讨论】:

  • 您的视图 class Payment(LoginRequiredMixin, View): 和模型名称相同,请尝试将您的视图名称更改为 class PaymentView(LoginRequiredMixin, View):
  • @NalinDobhal:如果您可以将您的评论变成答案,那么 Harsh Kushwah 可以批准它并关闭此问题。

标签: python django django-models django-views django-orm


【解决方案1】:

您的视图和模型具有相同的名称,这就是名称冲突的原因。

将您的视图更改为 PaymentView(或任何其他名称):

class PaymentView(LoginRequiredMixin, View):
    # rest of the code

【讨论】:

    【解决方案2】:

    您在 views.py 中使用 Payment 类名称,并且该 Payment 类在 models.py 中也是相同的。 Django 在获取 Payment 对象时感到困惑。请更改类名以确保正常工作。

    【讨论】:

      猜你喜欢
      • 2020-07-13
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 1970-01-01
      • 2020-12-19
      • 2022-11-29
      • 2019-08-27
      • 1970-01-01
      相关资源
      最近更新 更多