django url 异常 NoReverseMatch

django urls exceptions NoReverseMatch

美好的一天,我有一个 Django 项目,我想在其中 link 到 order_detail 但我收到此错误:django.urls.exceptions.NoReverseMatch: Reverse for 'orderdetail' with arguments '('',)' not found. 1 pattern(s) tried: ['orders/myorder/detail/(?P<order_id>[0-9]+)$']

models.py

from datetime import timezone

from django.contrib.auth.models import User

# Create your models here.
from django.db import models
from django.forms import ModelForm
from django.urls import reverse
from shop.models import Product
from decimal import Decimal
from django.core.validators import MinValueValidator, MaxValueValidator
from coupons.models import Coupon


class Order(models.Model):
    user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField()
    address = models.CharField(max_length=250)
    phone_number = models.CharField(max_length=20)
    city = models.CharField(max_length=100)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    paid = models.BooleanField(default=False)
    braintree_id = models.CharField(max_length=150, blank=True)
    reference_id = models.DateTimeField(auto_now_add=True, blank=True)
    coupon = models.ForeignKey(Coupon, related_name='orders', null=True, blank=True, on_delete=models.SET_NULL)
    discount = models.IntegerField(default=0, validators=[
        MinValueValidator(0),
        MaxValueValidator(100)
    ])

    class Meta:
        ordering = ('-created',)

    def __str__(self):
        return self.first_name

    def get_absolute_url(self):
        return reverse('orders:orderdetail', args=[self.id])

    def get_total_cost(self):
        total_cost = sum(item.get_cost() for item in self.items.all())
        return total_cost - total_cost * (self.discount / Decimal(100))

    def delivery_fee(self):
        fee = 500
        return fee

    def get_total_after_delivery(self):
        total = self.get_total_cost() + self.delivery_fee()
        return total


class OrderItem(models.Model):
    order = models.ForeignKey(Order,
                              related_name='items',
                              on_delete=models.CASCADE)
    product = models.ForeignKey(Product,
                                related_name='order_items',
                                on_delete=models.CASCADE)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.PositiveIntegerField(default=1)

    def __str__(self):
        return str(self.id)

    def get_cost(self):
        return self.price * self.quantity


class ShopCart(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
    quantity = models.PositiveIntegerField()

    def __str__(self):
        return str(self.product)

    @property
    def price(self):
        return self.product.price

    @property
    def cost(self):
        return self.quantity * self.price #self.product.price


class ShopCartForm(ModelForm):
    class Meta:
        model = ShopCart
        fields = ['quantity']

views.py

from django.contrib import messages
from django.urls import reverse
from django.shortcuts import render, redirect
from django.contrib.admin.views.decorators import staff_member_required
from django.shortcuts import get_object_or_404
from django.conf import settings
from django.http import HttpResponse, HttpResponseRedirect
from django.template.loader import render_to_string
import weasyprint
from cart.cart import Cart
from .models import OrderItem, Order, ShopCartForm, ShopCart
from .forms import OrderCreateForm
from .tasks import order_created

def order_list(request):
    current_user = request.user
    success = Order.objects.filter(user=current_user.id).filter(paid=True)
    fail = Order.objects.filter(user=current_user.id).filter(paid=False)
    return render(request, 'orders/order/order_list.html', {
        'success': success,
        'fail': fail,
        'current_user': current_user,
    })


def order_detail(request, order_id):
    order = get_object_or_404(Order, id=order_id)
    return render(request, 'orders/order/order_detail.html', {'order': order})

order/urls.py

from django.urls import path
from . import views

app_name = 'orders'

urlpatterns = [
    path('create/', views.order_create, name='order_create'),
    path('admin/order/<int:order_id>/', views.admin_order_detail, name='admin_order_detail'),
    path('admin/order/<int:order_id>/pdf/', views.admin_order_pdf, name='admin_order_pdf'),
    path('order/', views.order, name='order'),
    path('addtocart/<int:id>', views.addtocart, name='addtocart'),
    path('myorder/', views.order_list, name='orderlist'),
    path('myorder/detail/<int:order_id>', views.order_detail, name='orderdetail'),

]

project/urls.py

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('cart/', include('cart.urls', namespace='cart')),
    path('orders/', include('orders.urls', namespace='orders')),
    path('payment/', include('payment.urls', namespace='payment')),
    path('coupons/', include('coupons.urls', namespace='coupons')),
    path('members/', include('members.urls', namespace='members')),
    path('social-auth/', include('social_django.urls', namespace='social')),
    path('verification/', include('verify_email.urls')),
    path('', include('shop.urls', namespace='shop')),
    path('members/', include('django.contrib.auth.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

order_list.html

<a href="{% url 'orders:orderdetail' order_id %}" style="position: absolute; top: 5px; right: 5px;">View Details</a>

但是当我尝试这个 <a href="{order.get_absolute_url}" style="position: absolute; top: 5px; right: 5px;">View Details</a> 时,link 似乎不起作用,因为它指向任何地方。

此外,当我手动尝试 link 时,如下所示:https://buyerschoice.com:8000/orders/myorder/detail/69 我得到了想要的结果。

请问,我该如何解决这个问题? 谢谢

好吧,经过一番头脑风暴后,我意识到我遗漏了一些代码。 我只更新了我的 views.py

更新

views.py

def order_list(request):
    orders = Order.objects.all()
    current_user = request.user
    success = Order.objects.filter(user=current_user.id).filter(paid=True)
    fail = Order.objects.filter(user=current_user.id).filter(paid=False)
    return render(request, 'orders/order/order_list.html', {
        'success': success,
        'fail': fail,
        'current_user': current_user,
        'orders':orders,
    })

order_list.html

{% for order in orders%}
<a href="{{ order.get_absolute_url }}" style="position: absolute; top: 5px; right: 5px;">View Details</a>
{% endfor %}

并且有效。 :)