【问题标题】:Reverse for 'product_detail' with keyword arguments '{'slug': ''}' not found. 1 pattern(s) tried: ['products/detail/(?P<slug>[-a-zA-Z0-9_]+)/$']未找到带有关键字参数“{'slug': ''}' 的“product_detail”的反向操作。尝试了 1 种模式:['products/detail/(?P<slug>[-a-zA-Z0-9_]+)/$']
【发布时间】:2021-07-04 09:56:26
【问题描述】:

我试图用 slug 将 url 制作成人类可读的 url,而不是使用 Django 自动给我的pk。但是,它总是让我无法通过抛出 NoReverseMatch 将 slug 包含在我的 URL 中

这是与我的作品相关的代码。

models.py

from django.urls import reverse 

class Product(TimeStampModel):
    slug = models.SlugField(max_length=80, null=False, default='', editable=False)
    
    ...

    def save(self, *args, **kwargs):
        from django.utils.text import slugify 
        if not self.slug:
            self.slug = slugify(self.product_name, allow_unicode=True)
        super().save(*args, **kwargs)

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

views.py

  • ProductListView 是显示所有类别产品的视图
  • ProductDetailView是商品详情页视图。
from django.views.generic import DetailView, ListView

class ProductListView(ListView):
    model = models.Product
    template_name = 'products/product_all.html'
    context_object_name = 'products'
    paginate_by = 12
    paginate_orphans = 5
    ordering = 'created'

class ProductDetailView(DetailView):
    model = models.Product
    template_name = 'products/product_detail.html'
    context_object_name = 'products'

urls.py

from django.urls import path
from . import views 

app_name = 'products'

urlpatterns = [
    path('all/', views.ProductListView.as_view(), name='product_list_all'),
    paht('detail/<slug:slug>/', views.ProductDetailView.as_view(), name='product_detail'),
]

settings.py/urls.py

urlpatterns = [
    path('products/', include('products.urls', namespace='products')),
    ...
]

products/admin.py

我没有用 SlugField 对 admin.py 做任何事情

模板

  • ProductListView 的模板文件目录是 templates/products/product_all.html
  • ProductDetailView 的模板文件目录是 templates/products/product_detail.html
<section id="all" class="product-list">
    <ul class="item-grid">
        {% for product in products %}
        <li class="item">
            <a href="{{ product.get_absolute_url }}">
                <img src="{{ product.product_thumbnail.url }}" alt="product-image" class="product-image">
                <div class="product-info">
                    <h1 class="product-name">{{ product.product_name }}</h1>
                    <h2 class="product-price">{{ product.product_price }}</h2>
                </div>    
            </a>
        </li>
        {% endfor %}
    </ul>
</section>

我遇到了什么错误

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/products/all/

Django Version: 2.2.5
Python Version: 3.9.1
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'users.apps.UsersConfig',
 'common.apps.CommonConfig',
 'products.apps.ProductsConfig',
 'orders.apps.OrdersConfig',
 'compressor',
 'django_countries']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.locale.LocaleMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template /Users/apensia914/dev/knowner-website/templates/base.html, error at line 14
   Reverse for 'product_detail' with keyword arguments '{'slug': '반팔티2'}' not found. 1 pattern(s) tried: ['products/detail/(?P<slug>[-a-zA-Z0-9_]+)/$']
   4 : <!DOCTYPE html>
   5 : <html lang="en">
   6 : <head>
   7 :     <meta charset="UTF-8">
   8 :     <meta http-equiv="X-UA-Compatible" content="IE=edge">
   9 :     <meta name="viewport" content="width=device-width, initial-scale=1.0">
   10 :     {% compress css %}
   11 :         <link type="text/x-scss" rel="stylesheet" href="{% static 'scss/base.scss' %}">
   12 :     {% block style %}{% endblock style %}
   13 :     {% endcompress %}
   14 :     <title>{% block title %}{% e ndblock title %} | Knowner</ti tle>
   15 : </head>
   16 : <body>
   17 :     {% include 'partials/header.html' %}
   18 :     
   19 :     {% block content %}
   20 :     {% endblock content %}
   21 : 
   22 :     {% include 'partials/footer.html' %}
   23 :     <script src="https://kit.fontawesome.com/00dde58123.js" crossorigin="anonymous"></script>
   24 : </body>


Traceback:

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/core/handlers/base.py" in _get_response
  145.                 response = self.process_exception_by_middleware(e, request)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/core/handlers/base.py" in _get_response
  143.                 response = response.render()

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/response.py" in render
  106.             self.content = self.rendered_content

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/response.py" in rendered_content
  83.         content = template.render(context, self._request)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/backends/django.py" in render
  61.             return self.template.render(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in render
  171.                     return self._render(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in _render
  163.         return self.nodelist.render(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/loader_tags.py" in render
  150.             return compiled_parent._render(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in _render
  163.         return self.nodelist.render(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/loader_tags.py" in render
  62.                 result = block.nodelist.render(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/defaulttags.py" in render
  209.                     nodelist.append(node.render_annotated(context))

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in render
  987.             output = self.filter_expression.resolve(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in resolve
  671.                 obj = self.var.resolve(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in resolve
  796.             value = self._resolve_lookup(context)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/template/base.py" in _resolve_lookup
  858.                             current = current()

File "/Users/apensia914/dev/knowner-website/products/models.py" in get_absolute_url
  72.         return reverse('products:product_detail', kwargs=kwargs)

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/urls/base.py" in reverse
  90.     return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))

File "/Users/apensia914/.local/share/virtualenvs/knowner-website-tJGoHC0L/lib/python3.9/site-packages/django/urls/resolvers.py" in _reverse_with_prefix
  673.         raise NoReverseMatch(msg)

Exception Type: NoReverseMatch at /products/all/
Exception Value: Reverse for 'product_detail' with keyword arguments '{'slug': '반팔티2'}' not found. 1 pattern(s) tried: ['products/detail/(?P<slug>[-a-zA-Z0-9_]+)/$']


我确实通过了 slug 值,但它仍然无法捕捉。我犯了什么错误吗?

【问题讨论】:

  • self.slug = slugify(self.product_name, allow_unicode) 没有意义,应该是self.slug = slugify(self.product_name, allow_unicode=True)

标签: django django-models django-views


【解决方案1】:

表达式:

self.slug = slugify(self.product_name, allow_unicode)=True

没有意义,因为您将allow_unicode 的值作为参数传递,并将其分配给True。可能您的意思是:

self.slug = slugify(self.product_name<strong>, allow_unicode=True</strong>)

此外,如果一个对象没有被保存,或者.save() 被规避(例如通过在bulk 中创建记录,slug 将是空的)。您可以尝试通过以下方式解决此问题:

def get_absolute_url(self):
    kwargs = {
        'slug': self.slug or slugify(self.product_name, allow_unicode=True),
    }
    return reverse('products:product_detail', kwargs=kwargs)

您还应确保product_name 本身不为空(可能通过删除blank=True),并将其标记为unique=True

&lt;slug:…&gt; 目前仅适用于罗马字符,因此您需要指定一个 slug 字段:

from django.urls import re_path

urlpatterns = [
    path('all/', views.ProductListView.as_view(), name='product_list_all'),
    re_path('detail/(?<slug>[\w-])+/', views.ProductDetailView.as_view(), name='product_detail'),
]

【讨论】:

  • 首先,我为self.slug 的类型道歉。右括号应该是代码的结尾。我包含了具有唯一名称的product_name,但它仍然引发了与Reverse for 'product_detail' with keyword arguemtns {'slug': 'tshirts'} not found. 相同的问题
  • @DonghoonHan:你在urls.py中设置了app_name = ...吗?
  • @William 是的,我做到了。我将其命名为app_name = 'products'
  • 如果你使用allow_unicode=False会怎样?请注意,allow_unicode=True 可能导致值与slug 的 URL 路径转换器匹配。
  • @DonghoonHan:此时您需要使用re_path 指定URL,因为&lt;slug:...&gt; url 模式只接受带有罗马 字符的slug。
猜你喜欢
  • 1970-01-01
  • 2021-05-03
  • 2020-10-14
  • 1970-01-01
  • 2021-03-26
  • 2016-11-12
  • 2021-12-20
  • 2020-11-05
  • 1970-01-01
相关资源
最近更新 更多