首页 > 解决方案 > Django 删除 ListView 并将 DetailView 用于列表对象,然后给出 NoReverseMatch

问题描述

PyCharm 2020.2 Python 3.9 Django 3.1 Ubuntu 20.04 LTS

项目 urls.py:

 urlpatterns = [
    path('', views.home, name='home'),
    path('admin/doc/', include('django.contrib.admindocs.urls')),
    path('admin/', admin.site.urls),
    path('ktab/', include('ktab.urls')),

app.models.py:

 def get_absolute_url(self):
        return django.urls.reverse('EntryDetail_url', kwargs={"slug": self.slug})

应用程序.urls.py:

path('entry/index/', views.EntryIndex.as_view(), name='EntryIndex_url'),
path('entry/list/', views.EntryList.as_view(), name='EntryList_url'),
path('entry/<slug>:<title>/', views.EntryDetail.as_view(),  name='EntryDetail_url'),

app.views.py:

class EntryIndex(ListView):
    model = Entry
    template_name = 'EntryList_.html'

    def get_context_object_name(self, object_list):
        return 'object'

    def get_queryset(self):
        return Entry.objects.all()

    def get_context_data(self, **kwargs):
        context = super(EntryIndex, self).get_context_data(**kwargs)
        context['searchbox'] = SearchBox()
        return context

class EntryDetail(DetailView):
    model = Entry
    template_name = 'EntryDetail_.html'

    def get_context_data(self, **kwargs):
        context = super(EntryDetail, self).get_context_data(**kwargs)
        context['searchbox'] = SearchBox()
        return context

class EntryList(ListView):
    model = Entry
    template_name = 'EntryList_.html'

错误信息:

NoReverseMatch at /ktab/entry/list/
Reverse for 'EntryDetail_url' with keyword arguments '{'slug': 'executive-summary-hattie-urls-and-views'}' not found. 1 pattern(s) tried: ['ktab/entry/(?P<slug>[^/]+):(?P<title>[^/]+)/$']

……

In template /home/malikarumi/Projects/lifeandtimes/chronicle/templates/base_index.html, error at line 0

但是,当然,在第 0 行除了 DOCTYPE 声明之外什么都没有。

我正在尝试调用此模型对象的索引,这与列表相同。由于我不理解并且厌倦了与之抗争的原因,它一直试图在细节模板上给我一个对象。对象'executive-summary-hattie-urls-and-views'恰好是queryset [0]。

您可以看到我在 urls.py 中将 entry/index 和 entry/list 放在 entry/ 之前,希望它能够锁定它,但它拒绝这样做。

我正在使用基于类的视图。我尝试覆盖获取上下文名称并获取查询集,但这也没有任何区别。

在 Traceback 中,您可以看到一开始它确实获得了查询集:

context 
{'entry_list': <QuerySet [<Entry: Executive Summary of "hattie urls and views">, <Entry:....

当我试图弄清楚它在做什么时,它甚至更改了对象名称:

object_list': <QuerySet [<Entry: Executive Summary of "hattie urls and views">, <Entry:...

但它总是决定扼杀第一个。这是它改变的地方:

/home/malikarumi/.virtualenvs/chronic_all/lib/python3.9/site-packages/django/template/base.py,

line 858, in _resolve_lookup
                if callable(current):
                    if getattr(current, 'do_not_call_in_templates', False):
                        pass
                    elif getattr(current, 'alters_data', False):
                        current = context.template.engine.string_if_invalid
                    else:
                        try:  # method call (assuming no args required)
                  ----->    current = current() … ←---- 
                        except TypeError:
                            signature = inspect.signature(current)
                            try:
                                signature.bind()
                            except TypeError:  # arguments *were* required
                                current = context.template.engine.string_if_invalid  # invalid method call

Variable    Value
bit     'get_absolute_url'
context 
[{'True': True, 'False': False, 'None': None}, {}, {}, {'paginator': None, 'page_obj': None, 'is_paginated': False, 'object_list': <QuerySet [<Entry: Executive Summary of "hattie urls and views">, <Entry:'...(remaining elements truncated)...']>, 

'view': <ktab.views.EntryList object at 0x7f612c99cb20>}]
current 
<bound method Entry.get_absolute_url of <Entry: Executive Summary of "hattie urls and views">>
self    
<Variable: 'object.get_absolute_url'>
template_name   
'EntryList_.html'

模板:

{% for object in object_list %}
    <article class="blogpost">
    <header>
        <h2><a href="{{ object.get_absolute_url }}">{{ object.title }}</a></h2>

回溯中有5 次此行:

/home/malikarumi/.virtualenvs/chronic_all/lib/python3.9/site-packages/django/template/base.py, line 905, in render_annotated """ 渲染节点。如果debug为True并且渲染时出现异常, 异常用模板中发生的上下文行信息进行注释。对于内部使用,此方法优于直接使用 render 方法。"""

    try:
---->         return self.render(context) … ←---
        except Exception as e:
            if context.template.engine.debug and not hasattr(e, 'template_debug'):
                e.template_debug = context.render_context.template.get_exception_info(e, self.token)
            raise
    def __iter__(self):

我想这很重要,但我不知道它为什么这样做或如何撤消它。

我还尝试在 base.py 上的 PyCharm 中运行调试器:

File "/home/malikarumi/.virtualenvs/chronic_all/lib/python3.9/site-packages/django/template/base.py", line 69, in <module>
    from .exceptions import TemplateSyntaxError
ImportError: attempted relative import with no known parent package

这个项目大约有 4 年的历史,当然曾经工作过。现在我能得到的只有主页和管理员,它们都在项目 url 上,而不是应用程序上。谢谢。

21 年 7 月 31 日更新: @ShivendraPratapKushwaha 和 bdbd:首先,感谢你们俩试图帮助我。第二,是的,Shivenra,我今天下午在第一百万次重新阅读文档时注意到了这一点。我确信这些更改有所帮助,但这不是一个完整的解决方案。

bdbd,我猜你后来注意到了,我的 gau 已经在我的问题的第一部分。此外,我设法弄清楚如何使 PyCharm 的调试器工作。最终,这让我意识到我的模板中有“object.get_absolute_url”,而它应该是 url 模板标签和命名的 url。

您知道 Django 不会通知您缺少或拼写错误的模板变量吗?是的,我也没有。PyCharm 能告诉我的只有

Exception while resolving variable '%s' in template '%s'.

这有帮助还是什么?但它确实给了我一个很大的提示:变量“token”的停止和开始索引。这足以让我找到 object.get_absolute_url 并将其替换为 url 模板标签。

这是我学到的其他东西 - 我将详细介绍所有这些细节,因为找到这个非常耗时,也许它会在不久的将来帮助其他人,而不是不久的将来。当您从管理员单击“现场查看”时,它使用一个称为“快捷方式”的视图,而不是您自己的视图代码。我是从调试工具栏 (ddt) 得到的。因此,当您这样做时,您不会将苹果与苹果进行比较。然后我决定做一些真正激进的事情:我手动输入了单个实例的正确 url - 它出现了!正确!没有错误!

这是我目前的状态:

项目网址有效

该应用程序上有两个模型。如果我在 app.Model E 上输入一个详细实例的 url,它就可以工作。如果我在 app.Model W 上输入一个详细实例的 url,它会给我一个 NoReverseMatch 错误,由于它所说的参数,它没有多大意义。

如果我从管理员那里获得 app.Model E 或 app.Model W 的实例,我会收到一个 NoReverseMatch 错误,该错误似乎具有正确的参数,所以我对它为什么无法解决感到困惑。

我放弃了尝试让列表工作,直到我得到细节工作。现在要睡觉...

标签: pythondjangodjango-templates

解决方案


根据错误,绝对 url 与EntryDetail_url. 因此,要修复,更改 url 以正确使用正确的 kwarg 用于 slug:

path('entry/<slug:slug>/', views.EntryDetail.as_view(),  name='EntryDetail_url'),

并使用正确的 kwargsget_absolute_url来匹配 URL kwarg:

def get_absolute_url(self):
    from django.urls import reverse
    return reverse('EntryDetail_url', kwargs={'slug' : self.slug})

我正在尝试调用此模型对象的索引,这与列表相同。由于我不理解并且厌倦了与之抗争的原因,它一直试图在细节模板上给我一个对象。对象'executive-summary-hattie-urls-and-views'恰好是queryset [0]。

它为您提供了第一个对象,但是当它尝试调用它时失败get_absolute_url,因为 URL kwargs 不匹配导致的第一个错误。如果您真的希望模型对象调用索引(尽管我不清楚为什么),那么您需要更改get_absolute_urlofEntry以指向索引:

def get_absolute_url(self):
    from django.urls import reverse
    return reverse('EntryIndex_url')

推荐阅读