大家好,我想按照此网站https://djangopy.org/how-to/how-to-implement-categories-in-django/上的教程为帖子添加类别系统(我对代码做了些改动)
每次尝试转到类别页面查看该类别内的帖子时,都会收到此错误'NoneType' object has no attribute 'threads'
。
models.py:
from django.db import models
from django.urls import reverse
from django.utils.text import slugify
class Category(models.Model):
name = models.CharField(max_length=100)
short_desc = models.CharField(max_length=160)
slug = models.SlugField()
parent = models.ForeignKey('self', blank=True, null=True, related_name='children', on_delete=models.CASCADE)
class Meta:
unique_together = ('slug', 'parent',)
verbose_name_plural = "Categories"
def __str__(self):
full_path = [self.name]
k = self.parent
while k is not None:
full_path.append(k.name)
k = k.parent
return ' -> '.join(full_path[::-1])
def save(self, *args, **kwargs):
value = self.name
self.slug = slugify(value, allow_unicode=True)
super().save(*args, **kwargs)
class Thread(models.Model):
...
category = models.ForeignKey('Category', null=True, blank=True, on_delete=models.CASCADE, related_name='threads')
...
def get_cat_list(self):
k = self.category
breadcrumb = ["dummy"]
while k is not None:
breadcrumb.append(k.slug)
k = k.parent
for i in range(len(breadcrumb)-1):
breadcrumb[i] = '/'.join(breadcrumb[-1:i-1:-1])
return breadcrumb[-1:0:-1]
...
views.py:
from django.shortcuts import render, HttpResponseRedirect
from django.contrib import messages
from .models import Category, Thread
from .forms import SubmitScamNumber
def show_category_view(request, hierarchy=None):
category_slug = hierarchy.split('/')
category_queryset = list(Category.objects.all())
all_slugs = [ x.slug for x in category_queryset ]
parent = None
for slug in category_slug:
if slug in all_slugs:
#parent = get_object_or_404(Category, slug=slug, parent=parent)
parent = Category.objects.filter(slug__in=category_slug, parent=None).first()
context = {
'category': parent,
'threads': parent.threads.all(),
'sub_categories': parent.children.all(),
}
return render(request, "categories.html", context)
...
categories.html:
{% extends 'base.html' %}
{% block content %}
{% if sub_categories %}
<h3>Sub Categories</h3>
{% for i in sub_categories %}
<a href="{{ i.slug }}"> {{ i.name }} </a>
{% endfor %}
{% endif %}
{% if threads %}
{% for i in threads %}
<div class="columns">
<div class=" card-article-hover card">
<a href="{{ i.slug }}">
<img src="{{ i.cover_photo.url }}">
</a>
<div class="card-section">
<a href="{{ i.slug }}">
<h6 class="article-title">{{ i.title | truncatechars:30}}</h6>
</a>
</div>
<div class="card-divider flex-container align-middle">
<a href="" class="author">{{ i.user.get_full_name }}</a>
</div>
<div class="hover-border">
</div>
</div>
</div>
{% endfor %}
{% endif %}
{% endblock content %}
答案 0 :(得分:1)
在show_category_view
中设置parent = None
。然后,如果有任何从hierarchy
派生的块,则将它们循环并重新分配parent
作为Category
的实例。但是,如果在category_slug
或中没有任何标签,则在all_slugs
或中找不到该标签。返回Category.objects.filter(slug__in=category_slug, parent=None).first()
的实例,则Category
的值将保持为parent
,然后当您尝试访问{{1}的对象上的None
属性时},就像您在这里所做的一样……
threads
...您看到的异常将会发生。
由于错误告诉您None
,因为parent.threads.all() # parent = None
仍然是最初定义的'NoneType' object has no attribute 'threads'
。
此函数中还存在另一个null检查错误。
parent
您将None
参数的默认值设置为def show_category_view(request, hierarchy=None):
category_slug = hierarchy.split('/')
,然后在其上调用hierarchy
,即使该值可能是None
。如果您在split
上调用None
,则会抛出类似的split
。
您也不需要将None
投射到AttributeError
上。查询集已经像对象一样列出来了,可以被循环,实现迭代器协议等。(实际上,这样做可以丢弃查询集接口为您提供的所有好处。)在这里,您可以执行以下操作:
list