python Django - AttributeError at /blog/cat1 'NoneType' object has no attribute 'views'

4uqofj5v  于 11个月前  发布在  Python
关注(0)|答案(3)|浏览(151)

如果我尝试按类别获取博客文章,我会得到以下错误:AttributeError at /blog/cat 1 'NoneType' object has no attribute 'views' 'cat 1'是我在django管理面板categories are displaying correctly with post but when try to fetch posts by category i am getting error中为测试而创建的类别名称
pls check error image
这是我的models.py文件

from django.db import models
from django.contrib.auth.models import User
from django.utils.timezone import now
from ckeditor_uploader.fields import RichTextUploadingField

# Create your models here.
class Post(models.Model):
    sno = models.AutoField(primary_key=True)
    title = models.CharField(max_length=255)
    content = RichTextUploadingField()
    thumbnail = models.ImageField(upload_to='featured_image/%Y/%m/%d/')
    categories = models.ManyToManyField('Category', related_name='posts')
    author = models.CharField(max_length=15)
    slug = models.CharField(max_length=255)
    views = models.IntegerField(default=0)
    timeStamp = models.DateTimeField(blank=True)

    def __str__(self):
        return self.title + ' by ' + self.author
    
class Category(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        verbose_name_plural = "categories"

    def __str__(self):
        return self.name

class BlogComment(models.Model):
    sno = models.AutoField(primary_key=True)
    comment = models.TextField()
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True)
    timestamp = models.DateTimeField(default=now)
    def __str__(self):
        return self.comment[0:13] + "..." + "by " + self.user.username

字符串
Views.py

from django.shortcuts import render, redirect, get_object_or_404
from blog.models import Post, BlogComment, Category
from django.contrib import messages
from blog.templatetags import extras
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
import socket

# Create your views here.
def blogHome(request, tag_slug=None):
    allPosts = Post.objects.all().order_by("-timeStamp")
    # context = {'allPosts': allPosts}
    paginator = Paginator(allPosts, 5)
    page = request.GET.get('page')
    try:
        allPosts = paginator.page(page)
    except PageNotAnInteger:
        allPosts = paginator.page(1)
    except EmptyPage:
        allPosts = paginator.page(paginator.num_pages)

    return render(request, 'blog/blogHome.html', {'allPosts': allPosts, page:'pages'})

def blogCategory(request, pk):
    category = get_object_or_404(Category, pk=pk)
    return render(request, "blog/blogCategory.html", {'category': category})

def blogPost(request, slug):
    post = Post.objects.filter(slug=slug).first()
    post.views = post.views+1
    post.save()

    # comments
    comments = BlogComment.objects.filter(post=post, parent=None)
    replies = BlogComment.objects.filter(post=post).exclude(parent=None)
    replyDict = {}
    for reply in replies:
        if reply.parent.sno not in replyDict.keys():
            replyDict[reply.parent.sno] = [reply]
        else:
            replyDict[reply.parent.sno].append(reply)

    context = {'post': post, 'comments': comments, 'user': request.user, 'replyDict': replyDict}
    return render(request, 'blog/blogPost.html', context)

def postComment(request):
    if request.method == 'POST':
        comment = request.POST.get('comment')
        user = request.user
        postSno = request.POST.get('postSno')
        post = Post.objects.get(sno=postSno)
        parentSno = request.POST.get('parentSno')

        # new comment
        if parentSno == "":
            comment = BlogComment(comment=comment, user=user, post=post)
            comment.save()
            messages.success(request, 'Your comment has been posted successfully')
            
        # replies
        else:
            parent = BlogComment.objects.get(sno=parentSno)
            comment = BlogComment(comment=comment, user=user, post=post, parent=parent)
            comment.save()
            messages.success(request, 'Your reply has been posted successfully')

    return redirect(f'/blog/{post.slug}')


Urls.py

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

urlpatterns = [
    path('postComment', views.postComment, name='postComment'),
    path('', views.blogHome, name='blogHome'),
    path('<str:slug>', views.blogPost, name='blogPost'),
    path('category/<category>/', views.blogCategory, name='blogCategory'),
]


这是我的blogCategory.html模板(如果我渲染模板不正确请帮助我太)

{% extends "base.html" %}

{% block title %} Categories {% endblock title %}
{% block blogactive %} active {% endblock blogactive %}
{% block body %}
<div class="container my-4">
    <h2>Related Articles:</h2>
    {% if posts == posts %}
    <p>No such Category</p>
    Your search did not match any documents.<br>
    Suggestions: <br>
    <ul>
        <li>Make sure that all words are spelled correctly.</li>
        <li>Try different keywords.</li>
        <li>Try more general keywords.</li>
        <li>Try fewer keywords.</li>
    </ul>

    {% endif %}

    {% for category in post.categories.all %}

        <div class="card mb-3">
            <div class="card-body">
                <div class="row g-0">
                    <div class="col-md-4">
                        <div class="ratio ratio-16x9">
                        <!-- featured image --> 
                            <img src="{{ post.thumbnail.url }}" class="rounded featured-image-list" alt="{{post.title}}">
                        </div>
                    </div>
                    <div class="col-md-7 ps-md-3 pt-3 pt-md-0 d-flex flex-column">
                            <h2 class="card-title h3">
                                <a href="{{ post.slug }}">{{ post.title }}</a>
                            </h2>
                            <div class="text-muted">
                                <small>
                                    Published {{ post.timeStamp }} by <strong>{{ post.author }}</strong>
                                </small>
                            </div>
                            <p class="card-text mb-auto py-2">{{ post.content|safe|striptags|truncatechars:300 }}</p>
                            <div>
                                <a href="{{ post.slug }}" class="btn btn-primary">Read more</a> | Categories:
                                {% for category in post.categories.all %}
                                    <a href="{{ category.name }}">
                                        {{ category.name }}
                                    </a>
                                {% endfor %}
                            </div>
                    
                    </div>
                </div>
            </div>
        </div>

    {% endfor %}

</div>
{% endblock body %}


我期待什么:当任何人点击标签,他们应该看到该类别的博客文章

ctehm74n

ctehm74n1#

Raise erroe because**post = Post.objects.filter(slug=slug).first()**return None so.
尝试使用下面的代码片段

post = Post.objects.filter(slug=slug).first()
if post is not None:
   # Perform actions with the retrieved post
   post.views = post.views + 1
   post.save()

字符串
HTML中的变化

<h2 class="card-title h3">
    <a href="{% url 'blogPost' slug=post.slug %}">{{ post.title }}</a>
</h2>

-------- and ------
<div>
    <a href="{% url 'blogPost' slug=post.slug %}" class="btn btn-primary">Read more</a> | Categories:
    {% for category in post.categories.all %}
        <a href="{{ category.name }}">
            {{ category.name }}
        </a>
    {% endfor %}
</div>

fkvaft9z

fkvaft9z2#

这个错误发生时,我们没有模型上的对象,但我们要更新一些表,在这段代码中,你没有任何后对象,所以它没有,所以最好先检查是否有一个后。

post = Post.objects.filter(slug=slug).first()
if post is not None:
    post.views += 1
    post.save()

字符串

aelbi1ox

aelbi1ox3#

正如错误消息中所提到的,在views.py中,这个函数的第二行出现了一个错误:

def blogPost(request, slug):
    post = Post.objects.filter(slug=slug).first()
    post.views = post.views + 1  # Here
    post.save()

字符串
你会得到这种错误,因为你的模型找不到任何给定slug的记录(在这个例子中是cat1)。对于那个url(blog/cat1),你应该得到一个slug='cat1'的博客,但是正如你提到的,这里的cat1category,而不是slug
您需要在urls.py中进行一些更新并替换此:

path('category/<category>/', views.blogCategory, name='blogCategory'),


path('category/<str:category_name>/', views.blogCategory, name='blogCategory'),


models.py中进行以下更改:

class Category(models.Model):
    name = models.CharField(primary_key=True, max_length=50)


views.py中,使用以下内容更新blogCategory()视图:

def blogCategory(request, category_name):
    category = category = get_object_or_404(Category, pk=category_name)
    return render(request, "blog/blogCategory.html", {'category': category})


然后在你的模板中替换这个:

{% for category in post.categories.all %}
    <a href="{{ category.name }}">
        {{ category.name }}
    </a>
{% endfor %}


{% for category in post.categories.all %}
    <a href="{% url 'blogCategory' category.name %}">
        {{ category.name }}
    </a>
{% endfor %}


这一切都应该工作,但我会建议查看官方文档,以获得更多的经验和项目架构的建议。
以下是一些有用的链接:
Django urls
Django Forum: Best structure for urls
Django templates

相关问题