Django 模板中 {% url ...%} 与 {{ ... }} 的用法

The usage of {% url ...%} vs {{ ... }} in Django templates

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

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

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

如果我使用这段代码,它会工作得很好:

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

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

我的问题是为什么?

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

如果有人能解释为什么会这样,或者我哪里出错了,将不胜感激

网址:

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)

尝试 this.your 问题是您的 urls.py 中有一个名称空间,然后您应该在 href 中添加该名称空间('blog').

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

这个

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

上面的代码之所以有效,是因为您位于主页内,当您添加此代码时(在 a 标签中添加 href="{{ post.slug }}"),它只会调用当前的 url +"/<'slug:post_slug/' 这是一个有效的 url.but 这是一个非常糟糕的 option.use 第一个选项。
要了解此内容,请参阅此 https://docs.djangoproject.com/en/3.2/topics/http/urls/#url-namespaces.

在这种情况下,您应该使用: 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 }}

来自文档:

The logic here is that if you change the URL structure of your objects, even for something small like correcting a spelling error, you don’t want to have to track down every place that the URL might be created. Specify it once, in get_absolute_url() and have all your other code call that one place.