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>
虽然在不同的项目中工作,第一种方法可以正常工作,但这次不行。
我的问题是为什么?
这是我的 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)
尝试 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.
我一直在练习 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)
尝试 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.