【问题标题】:Django urls and views properly defined, still showing 404 error正确定义的 Django url 和视图,仍然显示 404 错误
【发布时间】:2020-08-22 00:20:52
【问题描述】:

我有一个博客正在运行,没有任何错误。不同的用户可以注册、登录和发布文章。用户可以在文章上编写/编辑/删除 cmets。以前,文章的 URL 是使用“文章 ID”决定的。后来,我阅读了this 教程,并在每篇文章的详细视图的 URL 中添加了 slug 和 id。然后我删除了我的旧文章,因为它们没有任何蛞蝓。

此更改后,用户可以成功创建评论,但不能“编辑”或“删除”任何评论。每当按下“编辑”或“删除”按钮时,都会显示 404 错误。 See the error image by pressing this link.

找不到页面 (404)

请求方法:GET

请求网址:http://localhost:8000/articles/33/comment_edit/

提出者:articles.views.ArticleDetailView

找不到与查询匹配的文章

我的对应文件如下:

urls.py(在文章应用目录内)

from django.urls import path
from .views import (ArticleListView, ArticleUpdateView, ArticleDetailView, ArticleDeleteView, ArticleCreateView, 
                    CommentCreateView, CommentUpdateView, CommentDeleteView)

urlpatterns = [
    path('', ArticleListView.as_view(), name='article_list'),
    path('<int:pk>/<str:slug>/edit/', ArticleUpdateView.as_view(), name='article_edit'),
    path('<int:pk>/<str:slug>/', ArticleDetailView.as_view(), name='article_detail'),
    path('<int:pk>/<str:slug>/delete/', ArticleDeleteView.as_view(), name='article_delete'),
    path('new/', ArticleCreateView.as_view(), name='article_new'),
    #Comments below
    path('<int:pk>/<str:slug>/comment/', CommentCreateView.as_view(), name='comment_new'),
    path('<int:pk>/comment_edit/', CommentUpdateView.as_view(), name='comment_edit'),
    path('<int:pk>/comment_delete/', CommentDeleteView.as_view(), name='comment_delete'),
]

我已经尝试通过注释掉 cmets 的 url 来运行该网站,即上面的最后三行。显示的错误是相同的。这很奇怪。

urls.py(在项目目录中)

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('users/', include('users.urls')),
    path('users/', include('django.contrib.auth.urls')),
    path('', include('pages.urls')),
    path('articles/', include('articles.urls')),
]

views.py(在文章应用目录内)

from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, DeleteView, CreateView
from django.urls import reverse_lazy
from .models import Article, Comment

# Create your views here.
class ArticleListView(ListView):
    model = Article
    template_name = 'article_list.html'
    ordering = ['-date']

class ArticleDetailView(DetailView):
    model = Article
    template_name = 'article_detail.html'
    query_pk_and_slug = True

class ArticleUpdateView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, UpdateView):
    model = Article
    fields = ('title', 'body',)
    template_name = 'article_edit.html'
    login_url = 'login'
    #def test_func for UserPassesTestMixin
    def test_func(self):
        obj = self.get_object()
        return obj.author == self.request.user
    success_message = 'Article was updated successfully!'        

class ArticleDeleteView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, DeleteView):
    model = Article
    template_name = 'article_delete.html'
    success_url = reverse_lazy('article_list')
    login_url = 'login'
    def test_func(self):
        obj = self.get_object()
        return obj.author == self.request.user
    success_message = 'Article was deleted successfully!'

class ArticleCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    model = Article
    fields = ('title', 'body')  
    template_name = 'article_new.html'
    login_url = 'login' #for LoginRequiredMixin, overriding default login url at accounts/login
    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)
    success_message = 'Article was created successfully!'    

#Now for the feature of adding comments on listview and detailview of articles
class CommentCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    model = Comment
    fields = ('comment',)
    template_name = 'comment_new.html'
    login_url = 'login'
    query_pk_and_slug = True
    def form_valid(self, form):
        form.instance.author = self.request.user
        form.instance.article = Article.objects.get(pk=self.kwargs['pk'])
        return super().form_valid(form)
    success_message = 'Comment was posted successfully!'    

class CommentUpdateView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, UpdateView):
    model = Comment
    fields = ('comment',)
    template_name = 'comment_edit.html'
    login_url = 'login'
    #def test_func for UserPassesTestMixin
    def test_func(self):
        obj = self.get_object()
        return obj.author == self.request.user
    success_message = 'Comment was updated successfully!'


class CommentDeleteView(LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, DeleteView):
    model = Comment
    template_name = 'comment_delete.html'
    success_url = reverse_lazy('article_list')
    login_url = 'login'
    def test_func(self):
        obj = self.get_object()
        return obj.author == self.request.user
    success_message = 'Comment was deleted successfully!'    

models.py(在 Articles App 目录中)

from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
from django.urls import reverse
from django.utils.text import slugify

User = get_user_model()
# Create your models here.
class Article(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(
        default='',
        editable=False,
        max_length=255,
    )
    body = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
    )
    def __str__(self):
        return self.title

    def get_absolute_url(self):
        kwargs = {
            'pk': self.id,
            'slug': self.slug
        }
        return reverse("article_detail", kwargs=kwargs)
    def save(self, *args, **kwargs):
        value = self.title
        self.slug = slugify(value, allow_unicode=True)
        super().save(*args, **kwargs)


class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='comments')
    comment = models.TextField()
    author = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
    )
    def __str__(self):
        return self.comment

    def get_absolute_url(self):
        kwargs = {
            'pk': self.article.id,
            'slug': self.article.slug
        }
        return reverse("article_detail", kwargs=kwargs)

任何 html 文件中用于创建评论、编辑评论和删除评论的链接如下所示:

<a href="{% url 'comment_new' article.pk article.slug %}">Add Comment</a>
<a href="{% url 'comment_edit' comment.pk %}">Edit Comment</a>
<a href="{% url 'comment_delete' comment.pk %}">Delete Comment</a>

在我的 settings.py 文件中,ALLOWED_HOSTS = ['*']

请帮我解决这个问题。我在网上搜索过,但没有找到任何解决方案。

【问题讨论】:

    标签: python django django-models django-views


    【解决方案1】:

    您是否在settings.py 中添加了您的应用名称?确保您已在位于项​​目文件夹下的 settings.py 中添加名称。

    这样,

    INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app_name',] # <--- WhatEver is called 
    

    还要确保您使用已定义的路线来访问正确的页面

    【讨论】:

    • 是的,我已经在 settings.py 文件中正确定义了已安装的应用程序。对于文章应用程序,我使用了'articles.apps.ArticlesConfig',其他应用程序也是如此。
    • 听起来不错。看到这个stackoverflow.com/a/51347762/6505847 看看这是否有帮助
    【解决方案2】:

    错误信息的重要部分是

    Raised by: articles.views.ArticleDetailView
    

    您正在尝试编辑/articles/33/comment_edit/ 的评论,但它与 URL 模式匹配:

    path('<int:pk>/<str:slug>/', ArticleDetailView.as_view(), name='article_detail'),
    

    这会给出 404,因为您没有 pk=33 和 slug='comment_edit' 的文章。

    您可以通过将CommentUpdateView 移动到ArticleDetailView 上方以使其首先匹配来解决此问题。

    【讨论】:

    • 我已经按照你说的做了。我将评论的 URL 移到了顶部。现在,评论可以顺利编辑了。但是现在,当我尝试删除评论时,会显示此错误,NoReverseMatch at /articles/28/comment_delete/ Reverse for 'article_detail' with arguments '(18,)' not found. 1 pattern(s) tried: ['articles/(?P&lt;pk&gt;[0-9]+)/(?P&lt;slug&gt;[^/]+)/$']
    • 这在另一个 URL 上,/articles/28/comment_delete/。查看错误with arguments '(18,)' - 您提供了主键但没有提供 slug。如果您仍然需要帮助,请提出一个新问题,因为这是一个不同的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 2012-09-09
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多