电子商务中没有反向匹配
No Reverse Match in Ecommerce
当转到 url "http://localhost:8000/compras/finalizando/" 时,引发以下错误:
“'pagseguro_view' 的反转,未找到参数“('',)'。尝试了 1 个模式:['compras/finalizando/(?P[0-9]+)/pagseguro/\Z']”
我不明白是什么导致了这个错误,有人可以帮忙吗?
我的checkout/urls.py:
from django.urls import path
from .import views
urlpatterns = [
path('carrinho/adicionar/<slug>', views.create_cartitem,name='create_cartitem'),
path('carrinho/', views.cart_item, name='cart_item'),
path('finalizando/', views.checkout, name='checkout'),
path('finalizando/<int:pk>/pagseguro/', views.pagseguro_view, name='pagseguro_view'),
path('meus-pedidos/', views.order_list, name='order_list'),
path('meus-pedidos/<int:pk>/', views.order_detail, name='order_detail'),
]
我的checkout/views.py:
from pagseguro import PagSeguro
from django.shortcuts import get_object_or_404, redirect
from django.views.generic import (
RedirectView, TemplateView, ListView, DetailView
)
from django.forms import modelformset_factory
from django.contrib import messages
from django.urls import reverse_lazy, reverse
from django.contrib.auth.mixins import LoginRequiredMixin
from catalog.models import Product
from .models import CartItem, Order
class CreateCartItemView(RedirectView):
def get_redirect_url(self, *args, **kwargs):
product = get_object_or_404(Product, slug=self.kwargs['slug'])
if self.request.session.session_key is None:
self.request.session.save()
cart_item, created = CartItem.objects.add_item(
self.request.session.session_key, product
)
if created:
messages.success(self.request, 'Produto adicionado com sucesso')
else:
messages.success(self.request, 'Produto atualizado com sucesso')
return reverse_lazy('checkout:cart_item')
class CartItemView(TemplateView):
template_name = 'checkout/cart.html'
def get_formset(self, clear=False):
CartItemFormSet = modelformset_factory(
CartItem, fields=('quantity',), can_delete=True, extra=0
)
session_key = self.request.session.session_key
if session_key:
if clear:
formset = CartItemFormSet(
queryset=CartItem.objects.filter(cart_key=session_key)
)
else:
formset = CartItemFormSet(
queryset=CartItem.objects.filter(cart_key=session_key),
data=self.request.POST or None
)
else:
formset = CartItemFormSet(queryset=CartItem.objects.none())
return formset
def get_context_data(self, **kwargs):
context = super(CartItemView, self).get_context_data(**kwargs)
context['formset'] = self.get_formset()
return context
def post(self, request, *args, **kwargs):
formset = self.get_formset()
context = self.get_context_data(**kwargs)
if formset.is_valid():
formset.save()
messages.success(request, 'Carrinho atualizado com sucesso')
context['formset'] = self.get_formset(clear=True)
return self.render_to_response(context)
class CheckoutView(LoginRequiredMixin, TemplateView):
template_name = 'checkout/checkout.html'
def get(self, request, *args, **kwargs):
session_key = request.session.session_key
if session_key and CartItem.objects.filter(cart_key=session_key).exists():
cart_items = CartItem.objects.filter(cart_key=session_key)
order = Order.objects.create_order(
user=request.user, cart_items=cart_items
)
else:
messages.info(request, 'Não há itens no carrinho de compras')
return redirect('checkout:cart_item')
return super(CheckoutView, self).get(request, *args, **kwargs)
class OrderListView(LoginRequiredMixin, ListView):
template_name = 'checkout/order_list.html'
paginate_by = 10
def get_queryset(self):
return Order.objects.filter(user=self.request.user)
class OrderDetailView(LoginRequiredMixin, DetailView):
template_name = 'checkout/order_detail.html'
def get_queryset(self):
return Order.objects.filter(user=self.request.user)
class PagSeguroView(LoginRequiredMixin, RedirectView):
def get_redirect_url(self, *args, **kwargs):
order_pk = self.kwargs['pk']
order = get_object_or_404(
Order.objects.filter(user=self.request.user), pk=order_pk
)
pg = order.pagseguro()
pg.redirect_url = self.request.build_absolute_uri(
reverse('checkout:order_detail', kwargs={'pk':order.pk})
)
#pg.notification_url = self.request.build_absolute_uri(
# reverse('checkout:pagseguro_notification')
#)
response = pg.checkout()
return response.payment_url
create_cartitem = CreateCartItemView.as_view()
cart_item = CartItemView.as_view()
checkout = CheckoutView.as_view()
order_list = OrderListView.as_view()
order_detail = OrderDetailView.as_view()
pagseguro_view = PagSeguroView.as_view()
我的checkout/models.py:
from pagseguro import PagSeguro
from django.db import models
from django.conf import settings
from catalog.models import Product
from django.db.models import F
class CartItemManager(models.Manager):
def add_item(self, cart_key, product):
if self.filter(cart_key=cart_key, product=product).exists():
created = False
cart_item = self.get(cart_key=cart_key, product=product)
cart_item.quantity = cart_item.quantity + 1
cart_item.save()
else:
created = True
cart_item = CartItem.objects.create(
cart_key=cart_key, product=product, price=product.price
)
return cart_item, created
class CartItem(models.Model):
cart_key = models.CharField(
'Chave do Carrinho', max_length=40, db_index=True
)
product = models.ForeignKey('catalog.Product',on_delete=models.DO_NOTHING, verbose_name='Produto')
quantity = models.PositiveIntegerField('Quantidade', default=1)
price = models.DecimalField('Preço', decimal_places=2, max_digits=8)
objects = CartItemManager()
class Meta:
verbose_name = 'Item do Carrinho'
verbose_name_plural = 'Itens dos Carrinhos'
unique_together = (('cart_key', 'product'),)
def __str__(self):
return '{} [{}]'.format(self.product, self.quantity)
class OrderManager(models.Manager):
def create_order(self, user, cart_items):
order = self.create(user=user)
for cart_item in cart_items:
order_item = OrderItem.objects.create(
order=order, quantity=cart_item.quantity, product=cart_item.product,
price=cart_item.price
)
return order
class Order(models.Model):
STATUS_CHOICES = (
(0, 'Aguardando Pagamento'),
(1, 'Concluída'),
(2, 'Preparando'),
(3, 'Enviado'),
(4, 'Finalizado'),
(5, 'Cancelada'),
)
PAYMENT_OPTION_CHOICES = (
('pix', 'Pix'),
('pagseguro', 'PagSeguro'),
('paypal', 'Paypal'),
)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name='Usuário')
status = models.IntegerField(
'Situação', choices=STATUS_CHOICES, default=0, blank=True
)
payment_option = models.CharField(
'Opção de Pagamento', choices=PAYMENT_OPTION_CHOICES, max_length=20,
default='deposit'
)
created = models.DateTimeField('Criado em', auto_now_add=True)
modified = models.DateTimeField('Modificado em', auto_now=True)
objects = OrderManager()
class Meta:
verbose_name = 'Pedido'
verbose_name_plural = 'Pedidos'
def __str__(self):
return 'Pedido #{}'.format(self.pk)
def products(self):
products_ids = self.items.values_list('product')
return Product.objects.filter(pk__in=products_ids)
def total(self):
aggregate_queryset = self.items.aggregate(
total=models.Sum(
models.F('price') * models.F('quantity'),
output_field=models.DecimalField()
)
)
return aggregate_queryset['total']
def pagseguro_update_status(self, status):
if status == '3':
self.status = 1
elif status == '7':
self.status = 2
self.save()
def complete(self):
self.status = 1
self.save()
def pagseguro(self):
self.payment_option = 'pagseguro'
self.save()
pg = PagSeguro(
email=settings.PAGSEGURO_EMAIL, token=settings.PAGSEGURO_TOKEN,
config={'sandbox': settings.PAGSEGURO_SANDBOX}
)
pg.sender = {
'email': self.user.email
}
pg.reference_prefix = ''
pg.shipping = None
pg.reference = self.pk
for item in self.items.all():
pg.items.append(
{
'id': item.product.pk,
'description': item.product.name,
'quantity': item.quantity,
'amount': '%.2f' % item.price
}
)
return pg
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE, verbose_name='Pedido', related_name='items')
product = models.ForeignKey('catalog.Product', on_delete=models.DO_NOTHING, verbose_name='Produto')
quantity = models.PositiveIntegerField('Quantidade', default=1)
price = models.DecimalField('Preço', decimal_places=2, max_digits=8)
class Meta:
verbose_name = 'Item do pedido'
verbose_name_plural = 'Itens dos pedidos'
def __str__(self):
return '[{}] {}'.format(self.order, self.product)
def post_save_cart_item(instance, **kwargs): # this function will be called when model CartItem be saved
if instance.quantity < 1:
instance.delete()
models.signals.post_save.connect(
post_save_cart_item, sender=CartItem, dispatch_uid='post_save_cart_item'
)
我的checkout/templates/checkout/checkout.html:
{% extends "base.html" %}
{% load static %}
{% block title %}
Finalização da Compra
{% endblock %}
{% block content %}
<ol class="breadcrumb">
<li><a href="{% url 'index' %}">Início</a></li>
<li><a href="{% url 'checkout:cart_item' %}">Carrinho de Compras</a></li>
<li class="active">Finalização da Compra</li>
</ol>
<div class="page-header">
<h1>Escolha forma de pagamento</h1>
</div>
<div class="row">
<div class="col-md-12">
<p>
Pedido #{{ order.pk }}
</p>
</div>
<div class="col-md-2 col-md-offset-1">
<a href="{% url 'checkout:pagseguro_view' order.pk %}" class="btn btn-success">
<img style="height:100px; width: 100px;" src="{% static 'images/pagseguro.png' %}">
>Pagar com Pagseguro
</a>
</div>
<div class="col-md-2 col-md-offset-1">
<a href="#" class="btn btn-success">
<img style="height:100px; width: 100px;" src="{% static 'images/paypal.png' %}">
>Pagar com Pagseguro
</a>
</div>
<div class="col-md-2 col-md-offset-1">
<a href="#" class="btn btn-success">
<img style="height:100px; width: 100px;" src="{% static 'images/pix.png' %}">
>Pagar com Pagseguro
</a>
</div>
</div>
{% endblock %}
不知道怎么回事,我觉得可能是id有问题
你能尝试在 checkout/templates/checkout/checkout 中更改此行吗?html:
href="{% url 'checkout:pagseguro_view' **order.pk** %}" class="btn btn-success"
到
href="{% url 'checkout:pagseguro_view' **pk=order.pk** %}" class="btn btn-success"
并尝试是否有错误更改。
在urls.py
改变你的路线,让pk
结束。
path("finalizando/pagseguro/<int:pk>",views.pagseguro_view,name='pagseguro_view')
如果这不起作用,则意味着 pk
是空的。
由于 CheckoutView
是一个模板视图,您需要使用 get_context_data
将 order
作为上下文变量发送。就像您在 CartItemView 中提到的表单集一样。
您正在使用 checkout/templates/checkout/checkout.html
中的订单,但那里不可用。
当转到 url "http://localhost:8000/compras/finalizando/" 时,引发以下错误:
“'pagseguro_view' 的反转,未找到参数“('',)'。尝试了 1 个模式:['compras/finalizando/(?P[0-9]+)/pagseguro/\Z']”
我不明白是什么导致了这个错误,有人可以帮忙吗?
我的checkout/urls.py:
from django.urls import path
from .import views
urlpatterns = [
path('carrinho/adicionar/<slug>', views.create_cartitem,name='create_cartitem'),
path('carrinho/', views.cart_item, name='cart_item'),
path('finalizando/', views.checkout, name='checkout'),
path('finalizando/<int:pk>/pagseguro/', views.pagseguro_view, name='pagseguro_view'),
path('meus-pedidos/', views.order_list, name='order_list'),
path('meus-pedidos/<int:pk>/', views.order_detail, name='order_detail'),
]
我的checkout/views.py:
from pagseguro import PagSeguro
from django.shortcuts import get_object_or_404, redirect
from django.views.generic import (
RedirectView, TemplateView, ListView, DetailView
)
from django.forms import modelformset_factory
from django.contrib import messages
from django.urls import reverse_lazy, reverse
from django.contrib.auth.mixins import LoginRequiredMixin
from catalog.models import Product
from .models import CartItem, Order
class CreateCartItemView(RedirectView):
def get_redirect_url(self, *args, **kwargs):
product = get_object_or_404(Product, slug=self.kwargs['slug'])
if self.request.session.session_key is None:
self.request.session.save()
cart_item, created = CartItem.objects.add_item(
self.request.session.session_key, product
)
if created:
messages.success(self.request, 'Produto adicionado com sucesso')
else:
messages.success(self.request, 'Produto atualizado com sucesso')
return reverse_lazy('checkout:cart_item')
class CartItemView(TemplateView):
template_name = 'checkout/cart.html'
def get_formset(self, clear=False):
CartItemFormSet = modelformset_factory(
CartItem, fields=('quantity',), can_delete=True, extra=0
)
session_key = self.request.session.session_key
if session_key:
if clear:
formset = CartItemFormSet(
queryset=CartItem.objects.filter(cart_key=session_key)
)
else:
formset = CartItemFormSet(
queryset=CartItem.objects.filter(cart_key=session_key),
data=self.request.POST or None
)
else:
formset = CartItemFormSet(queryset=CartItem.objects.none())
return formset
def get_context_data(self, **kwargs):
context = super(CartItemView, self).get_context_data(**kwargs)
context['formset'] = self.get_formset()
return context
def post(self, request, *args, **kwargs):
formset = self.get_formset()
context = self.get_context_data(**kwargs)
if formset.is_valid():
formset.save()
messages.success(request, 'Carrinho atualizado com sucesso')
context['formset'] = self.get_formset(clear=True)
return self.render_to_response(context)
class CheckoutView(LoginRequiredMixin, TemplateView):
template_name = 'checkout/checkout.html'
def get(self, request, *args, **kwargs):
session_key = request.session.session_key
if session_key and CartItem.objects.filter(cart_key=session_key).exists():
cart_items = CartItem.objects.filter(cart_key=session_key)
order = Order.objects.create_order(
user=request.user, cart_items=cart_items
)
else:
messages.info(request, 'Não há itens no carrinho de compras')
return redirect('checkout:cart_item')
return super(CheckoutView, self).get(request, *args, **kwargs)
class OrderListView(LoginRequiredMixin, ListView):
template_name = 'checkout/order_list.html'
paginate_by = 10
def get_queryset(self):
return Order.objects.filter(user=self.request.user)
class OrderDetailView(LoginRequiredMixin, DetailView):
template_name = 'checkout/order_detail.html'
def get_queryset(self):
return Order.objects.filter(user=self.request.user)
class PagSeguroView(LoginRequiredMixin, RedirectView):
def get_redirect_url(self, *args, **kwargs):
order_pk = self.kwargs['pk']
order = get_object_or_404(
Order.objects.filter(user=self.request.user), pk=order_pk
)
pg = order.pagseguro()
pg.redirect_url = self.request.build_absolute_uri(
reverse('checkout:order_detail', kwargs={'pk':order.pk})
)
#pg.notification_url = self.request.build_absolute_uri(
# reverse('checkout:pagseguro_notification')
#)
response = pg.checkout()
return response.payment_url
create_cartitem = CreateCartItemView.as_view()
cart_item = CartItemView.as_view()
checkout = CheckoutView.as_view()
order_list = OrderListView.as_view()
order_detail = OrderDetailView.as_view()
pagseguro_view = PagSeguroView.as_view()
我的checkout/models.py:
from pagseguro import PagSeguro
from django.db import models
from django.conf import settings
from catalog.models import Product
from django.db.models import F
class CartItemManager(models.Manager):
def add_item(self, cart_key, product):
if self.filter(cart_key=cart_key, product=product).exists():
created = False
cart_item = self.get(cart_key=cart_key, product=product)
cart_item.quantity = cart_item.quantity + 1
cart_item.save()
else:
created = True
cart_item = CartItem.objects.create(
cart_key=cart_key, product=product, price=product.price
)
return cart_item, created
class CartItem(models.Model):
cart_key = models.CharField(
'Chave do Carrinho', max_length=40, db_index=True
)
product = models.ForeignKey('catalog.Product',on_delete=models.DO_NOTHING, verbose_name='Produto')
quantity = models.PositiveIntegerField('Quantidade', default=1)
price = models.DecimalField('Preço', decimal_places=2, max_digits=8)
objects = CartItemManager()
class Meta:
verbose_name = 'Item do Carrinho'
verbose_name_plural = 'Itens dos Carrinhos'
unique_together = (('cart_key', 'product'),)
def __str__(self):
return '{} [{}]'.format(self.product, self.quantity)
class OrderManager(models.Manager):
def create_order(self, user, cart_items):
order = self.create(user=user)
for cart_item in cart_items:
order_item = OrderItem.objects.create(
order=order, quantity=cart_item.quantity, product=cart_item.product,
price=cart_item.price
)
return order
class Order(models.Model):
STATUS_CHOICES = (
(0, 'Aguardando Pagamento'),
(1, 'Concluída'),
(2, 'Preparando'),
(3, 'Enviado'),
(4, 'Finalizado'),
(5, 'Cancelada'),
)
PAYMENT_OPTION_CHOICES = (
('pix', 'Pix'),
('pagseguro', 'PagSeguro'),
('paypal', 'Paypal'),
)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name='Usuário')
status = models.IntegerField(
'Situação', choices=STATUS_CHOICES, default=0, blank=True
)
payment_option = models.CharField(
'Opção de Pagamento', choices=PAYMENT_OPTION_CHOICES, max_length=20,
default='deposit'
)
created = models.DateTimeField('Criado em', auto_now_add=True)
modified = models.DateTimeField('Modificado em', auto_now=True)
objects = OrderManager()
class Meta:
verbose_name = 'Pedido'
verbose_name_plural = 'Pedidos'
def __str__(self):
return 'Pedido #{}'.format(self.pk)
def products(self):
products_ids = self.items.values_list('product')
return Product.objects.filter(pk__in=products_ids)
def total(self):
aggregate_queryset = self.items.aggregate(
total=models.Sum(
models.F('price') * models.F('quantity'),
output_field=models.DecimalField()
)
)
return aggregate_queryset['total']
def pagseguro_update_status(self, status):
if status == '3':
self.status = 1
elif status == '7':
self.status = 2
self.save()
def complete(self):
self.status = 1
self.save()
def pagseguro(self):
self.payment_option = 'pagseguro'
self.save()
pg = PagSeguro(
email=settings.PAGSEGURO_EMAIL, token=settings.PAGSEGURO_TOKEN,
config={'sandbox': settings.PAGSEGURO_SANDBOX}
)
pg.sender = {
'email': self.user.email
}
pg.reference_prefix = ''
pg.shipping = None
pg.reference = self.pk
for item in self.items.all():
pg.items.append(
{
'id': item.product.pk,
'description': item.product.name,
'quantity': item.quantity,
'amount': '%.2f' % item.price
}
)
return pg
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE, verbose_name='Pedido', related_name='items')
product = models.ForeignKey('catalog.Product', on_delete=models.DO_NOTHING, verbose_name='Produto')
quantity = models.PositiveIntegerField('Quantidade', default=1)
price = models.DecimalField('Preço', decimal_places=2, max_digits=8)
class Meta:
verbose_name = 'Item do pedido'
verbose_name_plural = 'Itens dos pedidos'
def __str__(self):
return '[{}] {}'.format(self.order, self.product)
def post_save_cart_item(instance, **kwargs): # this function will be called when model CartItem be saved
if instance.quantity < 1:
instance.delete()
models.signals.post_save.connect(
post_save_cart_item, sender=CartItem, dispatch_uid='post_save_cart_item'
)
我的checkout/templates/checkout/checkout.html:
{% extends "base.html" %}
{% load static %}
{% block title %}
Finalização da Compra
{% endblock %}
{% block content %}
<ol class="breadcrumb">
<li><a href="{% url 'index' %}">Início</a></li>
<li><a href="{% url 'checkout:cart_item' %}">Carrinho de Compras</a></li>
<li class="active">Finalização da Compra</li>
</ol>
<div class="page-header">
<h1>Escolha forma de pagamento</h1>
</div>
<div class="row">
<div class="col-md-12">
<p>
Pedido #{{ order.pk }}
</p>
</div>
<div class="col-md-2 col-md-offset-1">
<a href="{% url 'checkout:pagseguro_view' order.pk %}" class="btn btn-success">
<img style="height:100px; width: 100px;" src="{% static 'images/pagseguro.png' %}">
>Pagar com Pagseguro
</a>
</div>
<div class="col-md-2 col-md-offset-1">
<a href="#" class="btn btn-success">
<img style="height:100px; width: 100px;" src="{% static 'images/paypal.png' %}">
>Pagar com Pagseguro
</a>
</div>
<div class="col-md-2 col-md-offset-1">
<a href="#" class="btn btn-success">
<img style="height:100px; width: 100px;" src="{% static 'images/pix.png' %}">
>Pagar com Pagseguro
</a>
</div>
</div>
{% endblock %}
不知道怎么回事,我觉得可能是id有问题
你能尝试在 checkout/templates/checkout/checkout 中更改此行吗?html:
href="{% url 'checkout:pagseguro_view' **order.pk** %}" class="btn btn-success"
到
href="{% url 'checkout:pagseguro_view' **pk=order.pk** %}" class="btn btn-success"
并尝试是否有错误更改。
在urls.py
改变你的路线,让pk
结束。
path("finalizando/pagseguro/<int:pk>",views.pagseguro_view,name='pagseguro_view')
如果这不起作用,则意味着 pk
是空的。
由于 CheckoutView
是一个模板视图,您需要使用 get_context_data
将 order
作为上下文变量发送。就像您在 CartItemView 中提到的表单集一样。
您正在使用 checkout/templates/checkout/checkout.html
中的订单,但那里不可用。