RedirectView 给出 NoReverseMatch

RedirectView give NoReverseMatch

我更改了博客文章的路径,使 url 更清晰。

之前 我有这条路径:

path("category/<slug:slug_category>/", views.singleCategory_postList, name="single_category"),
path("<slug:slug_post>/", views.singlePost, name='single_blog_post'),

现在我有这个:

path("<slug:slug_category>/", views.singleCategory_postList, name="single_category"),
path("<slug:slug_category>/<slug:slug_post>/", views.singlePost, name='single_blog_post'),

之前 get_absolute_url是这样的:

class Category(models.Model):
.....
    def get_absolute_url(self): 
        return reverse("single_category", kwargs={"slug_category": self.slug_category})


class BlogPost(ModelPost, TimeManager):
.....
    def get_absolute_url(self): 
        return reverse("single_blog_post", kwargs={"slug_post": self.slug_post})

现在是这样的:

class Category(models.Model):
.....
def get_absolute_url(self): 
    return reverse("single_category", kwargs={"slug_category": self.slug_category})


class BlogPost(ModelPost, TimeManager):
.....
def get_absolute_url(self): 
    return reverse("single_blog_post", kwargs={
                                            "slug_post": self.slug_post,
                                            "slug_category": self.category.slug_category,
                                            })

我正在尝试使用 RedirectView 来重定向所有旧路径;然后进入 urls.py 我现在有这个:

path("category/<slug:slug_category>/", RedirectView.as_view(pattern_name='single_category', permanent=True)),
path("<slug:slug_post>/", RedirectView.as_view(pattern_name='single_blog_post', permanent=True)),

path("categorie/", views.categoryList, name="list_category"),
path("<slug:slug_category>/", views.singleCategory_postList, name="single_category"),

path("", views.postList, name='list_post'),
path("<slug:slug_category>/<slug:slug_post>/", views.singlePost, name='single_blog_post'),

当我使用那些 RedirectView 时,它向我显示了这个错误:

NoReverseMatch at /blog/gis/

Reverse for 'single_blog_post' with keyword arguments '{'slug_post': 'gis'}' not found. 1 pattern(s) tried: ['blog\/(?P[-a-zA-Z0-9_]+)\/(?P[-a-zA-Z0-9_]+)\/$']

如果我评论这两个 RedirectView 路径,错误就会消失,我可以毫无问题地使用该站点,但是当我使用旧路径时,我会看到 404 错误。

我不明白 RedirectView 是如何工作的。有人可以给我举个例子吗?

问题是您的旧视图只需要 post 别名,而您的新视图还需要类别别名。但是,简单的 RedirectView 无法执行此重定向,因为它只能查看原始 URL 本身传递的参数。它不知道如何去数据库中找到类别 slug 并在重定向中使用它。

因此,您需要自己编写重定向视图。它可能非常简单:

def redirect_with_category(request, slug):
    post = get_object_or_404(Post, slug=slug)
    return redirect(post, permanent=True)

注意redirect会自动调用Post的get_absolute_url方法。另请注意,您要使用 permanent=True 到 return 301 而不是 302。