Django url 路径匹配未按预期工作
Django url path matching not working as expected
我对 Django 模型 get_absolute_url 反向方法有疑问。
我有一个完美运行的 url 模式,但问题是
当我访问 example.com/blog/python/first-post
时,路径完美运行,但是
当我尝试像 example.com/blog/python-randomr9353/first-post
这样的随机路径时
它仍然可以正常工作,即使它不应该因为 python-randomr9353
不是
一个有效的路径,它应该 return a page not found error
.
这是我的代码。
型号
class ArticleSeries(models.Model):
title = models.CharField(max_length=200)
series_slug = AutoSlugField(populate_from='title')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:article_list', kwargs={'series_slug': self.series_slug})
class Tag(models.Model):
title = models.CharField(max_length=50)
def __str__(self):
return self.title
class Article(models.Model):
title = models.CharField(max_length=200)
article_slug = AutoSlugField(populate_from='title')
tag = models.ManyToManyField(Tag, default=1, verbose_name='Tag')
series = models.ForeignKey(ArticleSeries, default=1, verbose_name='Series', on_delete=models.SET_DEFAULT)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:article_detail', args=(self.series.series_slug, self.article_slug))
url 模式
app_name = 'blog'
urlpatterns = [
path('', views.IndexView.as_view(), name='index_view'),
path('blog', views.BlogView.as_view(), name='blog_view'),
path('blog/<slug:series_slug>', views.ArticleListView.as_view(), name='article_list'),
path('blog/<slug:series_slug>/<slug:article_slug>', views.ArticleDetailView.as_view(), name='article_detail'),
]
观看次数
class IndexView(TemplateView):
template_name = 'blog/index.html'
extra_context = {}
class BlogView(ListView):
model = ArticleSeries
template_name = 'blog/blog_view.html'
context_object_name = 'series_list'
def get_queryset(self):
series = ArticleSeries.objects.all()
return get_list_or_404(series)
class ArticleListView(ListView):
model = Article
template_name = 'blog/article_list.html'
context_object_name = 'article_list'
def get_queryset(self):
slug = self.kwargs['series_slug']
articles = Article.objects.filter(series__series_slug=slug)
return get_list_or_404(articles)
class ArticleDetailView(DetailView):
model = Article
template_name = 'blog/article_detail.html'
context_object_name = 'article'
slug_field = 'article_slug'
slug_url_kwarg = 'article_slug'
def get_object(self, queryset=None):
slug = self.kwargs.get('article_slug')
return get_object_or_404(Article, article_slug=slug)
尝试在 urls.py
中使用 path('blog/python/<slug:article_slug>', views.ArticleDetailView.as_view(), name='article_detail')
而不是 path('blog/<slug:series_slug>/<slug:article_slug>', views.ArticleDetailView.as_view(), name='article_detail')
。
编辑:
在您获得 series_slug
的值时,请自行验证它。
...
validSeries = ['python', 'c', 'cpp', 'js'] # etc
if series_slug not in validSeries:
# Raise a page not found error
我对 Django 模型 get_absolute_url 反向方法有疑问。 我有一个完美运行的 url 模式,但问题是
当我访问 example.com/blog/python/first-post
时,路径完美运行,但是
当我尝试像 example.com/blog/python-randomr9353/first-post
这样的随机路径时
它仍然可以正常工作,即使它不应该因为 python-randomr9353
不是
一个有效的路径,它应该 return a page not found error
.
这是我的代码。
型号
class ArticleSeries(models.Model):
title = models.CharField(max_length=200)
series_slug = AutoSlugField(populate_from='title')
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:article_list', kwargs={'series_slug': self.series_slug})
class Tag(models.Model):
title = models.CharField(max_length=50)
def __str__(self):
return self.title
class Article(models.Model):
title = models.CharField(max_length=200)
article_slug = AutoSlugField(populate_from='title')
tag = models.ManyToManyField(Tag, default=1, verbose_name='Tag')
series = models.ForeignKey(ArticleSeries, default=1, verbose_name='Series', on_delete=models.SET_DEFAULT)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:article_detail', args=(self.series.series_slug, self.article_slug))
url 模式
app_name = 'blog'
urlpatterns = [
path('', views.IndexView.as_view(), name='index_view'),
path('blog', views.BlogView.as_view(), name='blog_view'),
path('blog/<slug:series_slug>', views.ArticleListView.as_view(), name='article_list'),
path('blog/<slug:series_slug>/<slug:article_slug>', views.ArticleDetailView.as_view(), name='article_detail'),
]
观看次数
class IndexView(TemplateView):
template_name = 'blog/index.html'
extra_context = {}
class BlogView(ListView):
model = ArticleSeries
template_name = 'blog/blog_view.html'
context_object_name = 'series_list'
def get_queryset(self):
series = ArticleSeries.objects.all()
return get_list_or_404(series)
class ArticleListView(ListView):
model = Article
template_name = 'blog/article_list.html'
context_object_name = 'article_list'
def get_queryset(self):
slug = self.kwargs['series_slug']
articles = Article.objects.filter(series__series_slug=slug)
return get_list_or_404(articles)
class ArticleDetailView(DetailView):
model = Article
template_name = 'blog/article_detail.html'
context_object_name = 'article'
slug_field = 'article_slug'
slug_url_kwarg = 'article_slug'
def get_object(self, queryset=None):
slug = self.kwargs.get('article_slug')
return get_object_or_404(Article, article_slug=slug)
尝试在 urls.py
中使用 path('blog/python/<slug:article_slug>', views.ArticleDetailView.as_view(), name='article_detail')
而不是 path('blog/<slug:series_slug>/<slug:article_slug>', views.ArticleDetailView.as_view(), name='article_detail')
。
编辑:
在您获得 series_slug
的值时,请自行验证它。
...
validSeries = ['python', 'c', 'cpp', 'js'] # etc
if series_slug not in validSeries:
# Raise a page not found error