在 Django 中获取 AttributeError
Getting AttributeError in Django
我在我的 Django 应用程序中使用 Stripe 处理付款。
每当我尝试填写虚拟卡凭据并提交时,都会出现以下错误。
AttributeError, 'Payment' object has no attribute 'save'
我不知道如何在 'views.py' 中保存付款对象。
我已经成功地在我的应用程序中应用了迁移并且已经迁移了它,但是我仍然收到这个错误。
以下是我的views.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
您在 views.py 中使用付款 class 名称并且此付款 class 在 models.py 中也是相同的。 Django 在获取 Payment 对象时感到困惑。请更改 class 名称以便正常工作。
您的视图和模型同名,这就是名称冲突的原因。
将您的视图更改为 PaymentView(或任何其他名称):
class PaymentView(LoginRequiredMixin, View):
# rest of the code
我在我的 Django 应用程序中使用 Stripe 处理付款。 每当我尝试填写虚拟卡凭据并提交时,都会出现以下错误。
AttributeError, 'Payment' object has no attribute 'save'
我不知道如何在 'views.py' 中保存付款对象。
我已经成功地在我的应用程序中应用了迁移并且已经迁移了它,但是我仍然收到这个错误。
以下是我的views.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
您在 views.py 中使用付款 class 名称并且此付款 class 在 models.py 中也是相同的。 Django 在获取 Payment 对象时感到困惑。请更改 class 名称以便正常工作。
您的视图和模型同名,这就是名称冲突的原因。
将您的视图更改为 PaymentView(或任何其他名称):
class PaymentView(LoginRequiredMixin, View):
# rest of the code