Django NoReverMatch 在 /

Django NoReverMatch at /

我读了书 'Django By Example' 和 运行 第 7 章中的示例。 但是结果调用"NoReverMatch at /"

NoReverseMatch at /
Reverse for 'product_detail' with arguments '(5, u'ironman')' and keyword arguments '{}' not found. 1 pattern(s) tried: ['(?P<id>[\d+])/(?P<slug>[-\w+])/$']

这是models.py

class Category(models.Model):
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True, unique=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'category'
        verbose_name_plural = 'categories'


    def __str__(self):
        return self.name


    def get_absolute_url(self):
        return reverse('shop:product_list_by_category', args=[self.slug])



class Product(models.Model):
    category = models.ForeignKey(Category, related_name='products')
    name = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(max_length=200, db_index=True)
    image = models.ImageField(upload_to='products/%Y/%m/%d', blank=True)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    stock = models.PositiveIntegerField()
    available = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('-created',)
        index_together = (('id', 'slug'),)


    def __str__(self):
        return self.name


    def get_absolute_url(self):
        return reverse('shop:product_detail', args=[self.id, self.slug])

这是urls.py

urlpatterns = [
url(r'^$', views.product_list, name='product_list'),
url(r'^(?P<category_slug>[-\w]+)/$', views.product_list, name='product_list_by_category'),
url(r'^(?P<id>\d+)/(?P<slug>[-\w+])/$', views.product_detail, name='product_detail'),
]

这是views.py

def product_list(request, category_slug=None):
    category = None
    categories = Category.objects.all()
    products = Product.objects.filter(available=True)
    if category_slug:
        category = get_object_or_404(Category, slug=category_slug)
        products = products.filter(category=category)

    return render(request, 'shop/product/list.html', {'category': category,   'categories': categories, 'products': products})



def product_detail(request, id, slug):
    product = get_object_or_404(Product,
                            id=id,
                            slug=slug,
                            available=True)

    return render(request, 'shop/product/detail.html', {'product': product})

这是发生错误的'list.html'模板。

{% extends "shop/base.html" %}
{% load static %}

{% block title %}
    {% if category %}{{ category.name }}{% else %}Products{% endif %}
{% endblock %}

{% block content %}
    <div id="sidebar">
        <h3>Categories</h3>
        <ul>
            <li {% if not category %} class="selected" {% endif %}>
                <a href="{% url 'shop:product_list' %}">All</a>
            </li>
            {% for c in categories %}
                <li {% if category.slug == c.slug %} class="selected" {% endif %}>
                    <a href="c.get_absolute_url">{{ c.name }}</a>
                </li>
            {% endfor %}
        </ul>
    </div>
    <div id="main" class="product-list">
        <h1>{% if category %}{{ category.name }}{% else %}Products{% endif %} </h1>
        {% for product in products %}
        <div class="item">
            <a href="{{ product.get_absolute_url }}">
                <img src="{% if product.image %}{{ product.image.url }}{% else %}{% static 'img/no_image.png' %}{% endif %}">
            </a>
            <a href="{{ product.get_absolute_url }}">{{ product.name }}</a><br>
           ${{ product.price }}
        </div>
        {% endfor %}
    </div>
{% endblock %}

错误发生在

<a href="{{ product.get_absolute_url }}">

-- 行。 为什么会出现这个错误??

在我看来你需要更改 url 模式:

url(r'^(?P<id>\d+)/(?P<slug>[-\w+])/$', views.product_detail, name='product_detail')

可能会:

url(r'^(?P<id>\d+)/(?P<slug>[-\w]+)/$', views.product_detail, name='product_detail')

'+' 不作为方括号内的特殊字符发挥作用,因此 [-\w+] 将仅匹配单个字符(字母数字或 '-'),但您传递的是多字符像 'ironman' 这样的字符串。 [-\w]+ 将匹配一个或多个字符。