【问题标题】:The usage of {% url ...%} vs {{ ... }} in Django templatesDjango 模板中 {% url ...%} 与 {{ ... }} 的用法
【发布时间】:2021-11-26 07:19:02
【问题描述】:

我一直在练习 Djnago,为此,我正在建立一个博客。在构建它的过程中,我遇到了一个错误,同时使用以下代码:

<a href="{% url 'blog_post' post.slug %}">
    {{ post.title }}
</a>

在学习和做其他课程时,这样的事情会很好。但是现在,它会引发这个异常:NoReverseMatch

如果我使用此代码,它会正常工作:

<a href="{{ post.slug }}">
    {{ post.title }}
</a>

虽然在不同的项目中工作,第一种方法可以正常工作,但这次不行。

我的问题是为什么?

这是我的 urls 和我的 views 中的代码。也许错误就在这里,而不是其他地方。

如果有人能解释为什么会发生这种情况,或者我哪里出错了,我们将不胜感激

网址

from django.urls import path

from . import views

app_name = 'blog'

urlpatterns = [
    path('', views.blog_index, name='blog_index'),
    path('<slug:post_slug>/', views.blog_post, name='blog_post'),
]

观看次数

from django.shortcuts import render
from .models import Post

# Create your views here.
def blog_index(request):
    posts = Post.objects.order_by('- 
    created').filter(published=True)
    data = {
        'posts': posts
    }
    return render(request, 'blog/post_list.html', data)

def blog_post(request, post_slug):
    post = Post.objects.get(slug=post_slug)
    data = {
        'post': post
    }
    return render(request, 'blog/post_detail.html', data)

【问题讨论】:

  • 请始终发布带有完整追溯整个错误消息NoReverseMatch 不足以调试问题。
  • @Selcuk 至少(希望如此?我没有测试)有一个minimal reproducible example
  • @user202729 不,没有。我们不知道导致初学者出现问题的输入 (post)。此外,MCVE 不是缺少调试信息(例如错误消息)的借口。
  • @Selcuk 谢谢!我已经用 Django 给出的错误消息的打印更新了这个问题。我相信现在更清楚了。

标签: python django django-urls


【解决方案1】:

试试这个。你的问题是你的 urls.py 中有一个命名空间,那么你应该在你的 href 中添加那个命名空间('blog')。

<a href="{% url 'blog:blog_post' post.slug %}">
    {{ post.title }}
</a>

这个

 <a href="{{ post.slug }}">
    {{ post.title }}
</a>

上面的代码可以正常工作,因为您位于主页内,当您在 a 标签中添加 this(href="{{ post.slug }}" 时)它只会调用当前 url +"/ 要了解这一点,请参阅此https://docs.djangoproject.com/en/3.2/topics/http/urls/#url-namespaces

【讨论】:

  • 更具体地说,问题是“为什么?”,而不是“你能给我代码吗?”
  • @user202729 感谢您的建议。问题是我的英语不太好。但我再次编辑了我的答案。
  • 在模板中执行此类操作是不好的做法
【解决方案2】:

在这种情况下,您应该使用: https://docs.djangoproject.com/en/3.2/ref/models/instances/#get-absolute-url 模板中的逻辑越少,对应用程序越好。 很难对模板中包含的逻辑编写测试。

你应该给你的模型添加一个方法:

from django.urls import reverse

class Post()
    ...
    def get_absolute_url(self):
        return reverse('blog:blog_post', kwargs={'post_slug' : self.slug})

在反向函数中,您需要添加一个应用程序命名空间。 在你的情况下,它是一个博客。 https://docs.djangoproject.com/en/3.2/topics/http/urls/#introduction

然后在模板中使用:

{{ post.get_absolute_url }}

来自文档:

这里的逻辑是,如果您更改对象的 URL 结构,即使是为了更正拼写错误之类的小事,您也不希望跟踪可能创建 URL 的每个位置。在 get_absolute_url() 中指定一次,然后让所有其他代码调用该位置。

【讨论】:

  • 虽然技术上是正确的,但这并不是对所提问题的回答。我们不知道 OP 的代码失败的原因,reverse 在同样的情况下也会和{% url %} 一样失败。
  • 我添加了应添加应用程序命名空间的信息。我编写了工作代码,但实际上我忘记了它可能并不明显。 @塞尔丘克
  • 您的回答对我很有效。我选择另一个答案作为熟悉的正确答案,但是,你的似乎也是一个不错的选择。仍在尝试找出哪个是更好的做法。我会调查这个。谢谢!
猜你喜欢
  • 2012-01-04
  • 2010-12-19
  • 2013-05-06
  • 2023-03-28
  • 2017-06-14
  • 2018-11-03
  • 1970-01-01
  • 1970-01-01
  • 2018-03-01
相关资源
最近更新 更多