我是django的新手,我正在学习一些教程来学习它。在本教程中,我试图建立一个博客,但是我陷于以下错误中。
First argument to get_object_or_404() must be a Model, Manager, or QuerySet, not 'unicode'.
Request Method: GET
Request URL: http://localhost:8000/blog/2018/10/16/todays_post/
Django Version: 1.11.16
Exception Type: ValueError
Exception Value:First argument to get_object_or_404() must be a Model, Manager, or QuerySet, not 'unicode'.
Exception Location: C:\Users\...\mysite\python-ve\env\lib\site-packages\django\shortcuts.py in get_object_or_404, line 90
Python Executable: C:\Users\...\mysite\python-ve\env\Scripts\python.exe
Python Version: 2.7.15
以下是我的模型。py
from __future__ import unicode_literals
from django.core.urlresolvers import reverse
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class PublishedManager(models.Manager):
def get_queryset(self):
return super(PublishedManager,self).get_queryset()\
.filter(status='published')
class post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published','Published'),
)
title = models.CharField(max_length=250) # field for the post title
slug = models.SlugField(max_length=250, unique_for_date='publish')
author = models.ForeignKey(User, related_name ='blog_posts')
body = models.TextField()# text field. body of the post
publish = models.DateTimeField(default=timezone.now)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
status = models.CharField(max_length = 10,
choices=STATUS_CHOICES,default='draft') # to know the status of the post
objects = models.Manager()
published = PublishedManager()
class Meta: # sort results by the publish field in descending order
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog:post_detail', args[self.publish.year,
self.publish.strftime('%m'), self.publish.strftime('%d'), self.slug])
我的views.py,其中例外是:
from __future__ import unicode_literals
from django.shortcuts import render, get_object_or_404
from .models import post
def post_list(request):
posts = post.published.all()
return render(request, 'blog/post/list.html',{'posts':posts})
def post_detail(request, year, month,day,post):
post = get_object_or_404(post, slug=post, status='published',
publish_year=year, publish_month=month, publish_day=day)
return render(request, 'blog/post/detail.html', {'post':post})
我一直在寻找答案,有些我无法理解,所以我将其发布在这里。
答案 0 :(得分:1)
视图中的变量和类的名称均为post
,这意味着在您的视图中,我们看到:
def post_detail(request, year, month,day, post):
post = get_object_or_404(post, slug=post, status='published',
publish_year=year, publish_month=month, publish_day=day)
return render(request, 'blog/post/detail.html', {'post':post})
因此, post
本身是包含slug
的局部变量(参数),并且它“隐藏”了引用模型的外部变量post
。我建议您遵循 PEP-8 ,然后将您的post
类重命名为Post
(以大写字母开头,并且以驼峰字母开头)。如果您始终遵循PEP-8,则通常不会发生局部变量与类名之间的冲突。
一种快速(而不是优雅的)修复方法是使用其他名称导入模型:
from __future__ import unicode_literals
from django.shortcuts import render, get_object_or_404
from .models import post as post_model
def post_list(request):
posts = post_model.published.all()
return render(request, 'blog/post/list.html',{'posts':posts})
def post_detail(request, year, month,day,post):
post = get_object_or_404(post_model, slug=post, status='published',
publish_year=year, publish_month=month, publish_day=day)
return render(request, 'blog/post/detail.html', {'post':post})
但是我认为简单地使您的变量符合PEP-8绝对值得付出努力。
答案 1 :(得分:1)
将您的post
类重命名为Post
,并在post_detail
视图中使用它。
post = get_object_or_404(Post, slug=post, status='published', publish_year=year, publish_month=month, publish_day=day)
在您的代码get_object_or_404
中,函数尝试将视图中的post
参数用作模型,但这是unicode。
对于类名,也要遵循UpperCaseCamelCase约定。
答案 2 :(得分:0)
重命名此代码块中的帖子
def post_detail(request, year, month,day, slug):
post = get_object_or_404(post, slug=slug, status='published',
publish_year=year, publish_month=month, publish_day=day)
return render(request, 'blog/post/detail.html', {'post':post})
然后要特别提示,因为模型是类,所以总是以大写字母开头来表示模型名称,这是一些好习惯。