简体   繁体   English

Django url 和视图正确定义,仍然显示 404 错误

[英]Django urls and views properly defined, still showing 404 error

I have a blog which was running without any error.我有一个博客运行没有任何错误。 Different users can register, login, and post articles.不同的用户可以注册、登录和发布文章。 Users can write/edit/delete comments on the articles.用户可以对文章撰写/编辑/删除评论。 Previously, the URL of the articles were decided using 'article id'.以前,文章的 URL 是使用“文章 ID”决定的。 Later, I read this tutorial and added slug along with id in the URL for every article's Detail View.后来,我阅读了本教程,并在每篇文章的详细视图的 URL 中添加了 slug 和 id。 Then I deleted my old articles since they didn't have any slugs.然后我删除了我的旧文章,因为它们没有任何蛞蝓。

After this change, a user can create a comment successfully, but cannot 'edit' or 'delete' any comment.在此更改之后,用户可以成功创建评论,但不能“编辑”或“删除”任何评论。 Whenever 'edit' or 'delete' button is pressed, 404 error is shown.每当按下“编辑”或“删除”按钮时,都会显示 404 错误。 See the error image by pressing this link .按此链接查看错误图像

Page not found (404)找不到页面 (404)

Request Method: GET请求方法:GET

Request URL: http://localhost:8000/articles/33/comment_edit/请求 URL: http://localhost:8000/articles/33/comment_edit/

Raised by: articles.views.ArticleDetailView提出者:articles.views.ArticleDetailView

No article found matching the query未找到与查询匹配的文章

My corresponding files are listed below:我的相应文件如下:

urls.py (inside Articles App directory) urls.py (在 Articles App 目录中)

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'),
]

I have tried and run the website by commenting out the url for comments, ie, the last three lines above.我已经尝试通过将 url 注释掉来运行该网站,即上面的最后三行。 The error shown is the same.显示的错误是相同的。 This is strange.这很奇怪。

urls.py (inside Project directory) 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 (inside Articles App directory) views.py (在 Articles App 目录中)

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 (inside Articles App directory) 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)

The links for creating a comment, editing a comment, and deleting a comment in any html file looks like this:在任何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>

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

Kindly help me with this problem.请帮我解决这个问题。 I have searched online but didn't find any solution.我在网上搜索过,但没有找到任何解决方案。

The important part of the error message is错误消息的重要部分是

Raised by: articles.views.ArticleDetailView

You are trying to edit a comment at /articles/33/comment_edit/ , but it is matching the URL pattern:您正在尝试在/articles/33/comment_edit/编辑评论,但它与 URL 模式匹配:

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

This gives a 404, because you don't have an article with pk=33 and slug='comment_edit'.这给出了 404,因为您没有 pk=33 和 slug='comment_edit' 的文章。

You could fix the issue by moving the CommentUpdateView above ArticleDetailView so that it matches first.您可以通过将ArticleDetailView移动到CommentUpdateView上方来解决此问题,以便它首先匹配。

Have you added your app name inside settings.py ?您是否在settings.py添加了您的应用名称? Make sure you have added the name in settings.py which resides under the project folder.确保您已在位于项目文件夹下的 settings.py 中添加名称。

Like so,像这样,

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 

And also make sure you are using your routes you have defined to access the correct page并确保您使用您定义的路线来访问正确的页面

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM