当我制作 post 并点击 "PUBLISH BUTTON" 时显示 "Blog" Object is not iterable 错误
When i make a post and hit the "PUBLISH BUTTON" is shows a "Blog" Object is not iterable error
我尝试了很多使用过滤器的方法,因为 get 尝试获取单个对象但它仍然有效。当我从我的管理部分制作 post 时,一切正常,但是当我使用表单从我的前端制作 post 时,它会创建 posts 然后显示对象不可迭代“注意: posts 创建得非常好”但是我得到了可迭代的错误,而且 slug 不会像在后端管理部分那样自动填充到前端。任何帮助都会非常有用,并使我的工作更快。
让我展示一些我的代码
views.py
#this is for allowing user to create a new post from the frontend
def blogpost(request):
if request.method == "POST":
form = BlogPostForm(request.POST, request.FILES)
if form.is_valid():
form = form.save(commit=False)
form.creator = request.user
form.save()
messages.success(request, f'Hi, Your Post have been sent for review and would be live soon!')
else:
form = BlogPostForm()
context = {
"form": form
}
return render(request, 'blog/AddPost.html', context)
#this is for listing all the blog posts
def BlogList(request):
posts = Blog.objects.filter(status='published').order_by('-created').values()
categoriess = Category.objects.all()
context = {
'posts': posts,
'categories': categoriess,
}
return render(request, 'blog/bloghome.html', context)
# This is view for blog details
def BlogDetail(request, blog_slug):
post = get_object_or_404(Blog, slug=blog_slug)
# post = Blog.objects.filter(slug=blog_slug)
categories = Category.objects.all()
comments = post.comments.filter(active=True)
new_comment = None
if request.method == "POST":
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
new_comment = comment_form.save(commit=False)
new_comment.post = post
new_comment.name = request.user
new_comment.save()
else:
comment_form = CommentForm()
forms.py
class BlogPostForm(forms.ModelForm):
class Meta:
model = Blog
fields = ['title', 'slug', 'content', 'image', 'category', 'tags']
models.py
class Blog(models.Model):
title = models.CharField(max_length=10000, null=True, blank=True, verbose_name="Title")
content = models.TextField(verbose_name="Post Content")
slug = models.SlugField(unique=True)
image = models.ImageField(upload_to="blog-images/%Y/%m/%d/", verbose_name="Post Thumbnail")
category = models.ForeignKey(Category, on_delete=models.DO_NOTHING, verbose_name="Category", null=True)
tags = models.ManyToManyField(Tag, related_name='tags', verbose_name="Tag", null=True)
status = models.CharField(choices=STATUS_CHOICE, default="published", max_length=150, verbose_name='Status')
creator = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="Creator", null=True)
created = models.DateTimeField(auto_now_add=True ,verbose_name="Created", null=True)
def get_absolute_url(self):
return reverse('blog:blog-details', args=[self.slug])
class Meta:
verbose_name = "Blog Post"
verbose_name_plural = "Blog Posts"
def __str__(self):
return self.title
urls.py
urlpatterns = [
path('', views.BlogList, name="home"),
path('post/<slug:blog_slug>', views.BlogDetail, name="blog-details"),
path('post/categories/<slug:category_slug>', views.category, name="category"),
path('post/tags/<slug:tag_slug>', views.tag, name="tags"),
path('post/create/', views.blogpost, name="add-post"),
bloghome.html
<!-- this would list out all the blog post -->
{% for post in posts %}
<div class="col-lg-4 col-md-6 col-sm-12">
<div class="articles_grid_style style-2">
<div class="articles_grid_thumb">
<a href="{{post.get_absolute_url}}"><img src="{{post.image.url}}" class="img-fluid" alt="" style="width: 450px; height: 250px;"></a>
</div>
<div class="articles_grid_caption">
<div class="mpd-date-wraps">
<!-- <span class="mpd-meta-date">10</span> -->
<span class="mpd-meta-month">{{post.created|date:"d, M Y"}}</span>
</div>
<div class="blog-grid-cat" style="background: rgb(161, 161, 161); color: white;">{{post.category}}</div>
<a href="{{post.get_absolute_url}}"><h4>{{post.title|truncatechars:70}}</h4></a>
<div class="articles_grid_desc">
<p style="color: black;">{{post.content|truncatechars:80}}</p>
</div>
</div>
<div class="articles_grid_caption-footer">
<div class="articles_grid_author">
<div class="articles_grid_author_img"><img src="{{post.creator.profile.image.url}}" class="img-fluid" alt=""></div>
<a href="">
<h4>{{post.creator.profile.first_name}} {{post.creator.profile.last_name}}</h4>
</a>
</div>
<div class="footer-flex-last">
<a href="{{post.get_absolute_url}}" class="bl-detail-view" style="background:linear-gradient(230deg, rgb(255, 0, 157) 0%, rgb(111, 0, 255) 100%), url(assets/img/tag-light.png) no-repeat; color: white;"><b>READ MORE</b></a>
</div>
</div>
</div>
</div>
{% endfor %}
addpost.html
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form|crispy}}
<div class="form-group">
<button class="btn theme-bg rounded" type="submit">Send Message</button>
</div>
</form>
blogdetails.html
<div class="post-featured-img">
<img class="img-fluid" src="{{ post.image.url }}" alt="">
</div>
<div class="post-top-meta">
<ul class="meta-comment-tag">
<li><a href="#"><span class="icons"><i class="ti-user"></i></span>by {{ post.creator.profile.first_name }} {{ post.creator.profile.last_name }}</a></li>
<li><a href="#"><span class="icons"><i class="ti-comment-alt"></i></span>{{comments.count}} Comments</a></li>
</ul>
</div>
<h2 class="post-title">{{ post.title }}</h2>
<p style="color: black;">{{ post.content }}<p>
如果能看到您的模板代码会很有帮助,但这里有一些我看到的问题。
首先,您的 blogpost
观点。当您执行 POST 请求时,在保存表单并设置成功消息后,重定向到 BlogDetail
视图。按照您的编码方式,保存表单后它将再次呈现 blogpost
视图,这次是包含请求 POST 数据的表单。查找 redirect
here.
其次,在您的 BlogList
视图中,您正在 posts
查询集上调用 .values()
。没有看到您的模板代码,我无法判断这是否是故意的,但请确保您知道查询集中的 values()
return 是什么。您可能不想使用它。
第三,您的 BlogDetail
视图没有 return 任何东西,您需要 return HttpResponse 使用例如 render
就像您的其他视图一样。
最后要注意的是,它的通用约定是以小写形式命名基于函数的视图,其中 _ 为 space。 CamelCase 保留用于基于 class 的视图。
我尝试了很多使用过滤器的方法,因为 get 尝试获取单个对象但它仍然有效。当我从我的管理部分制作 post 时,一切正常,但是当我使用表单从我的前端制作 post 时,它会创建 posts 然后显示对象不可迭代“注意: posts 创建得非常好”但是我得到了可迭代的错误,而且 slug 不会像在后端管理部分那样自动填充到前端。任何帮助都会非常有用,并使我的工作更快。 让我展示一些我的代码
views.py
#this is for allowing user to create a new post from the frontend
def blogpost(request):
if request.method == "POST":
form = BlogPostForm(request.POST, request.FILES)
if form.is_valid():
form = form.save(commit=False)
form.creator = request.user
form.save()
messages.success(request, f'Hi, Your Post have been sent for review and would be live soon!')
else:
form = BlogPostForm()
context = {
"form": form
}
return render(request, 'blog/AddPost.html', context)
#this is for listing all the blog posts
def BlogList(request):
posts = Blog.objects.filter(status='published').order_by('-created').values()
categoriess = Category.objects.all()
context = {
'posts': posts,
'categories': categoriess,
}
return render(request, 'blog/bloghome.html', context)
# This is view for blog details
def BlogDetail(request, blog_slug):
post = get_object_or_404(Blog, slug=blog_slug)
# post = Blog.objects.filter(slug=blog_slug)
categories = Category.objects.all()
comments = post.comments.filter(active=True)
new_comment = None
if request.method == "POST":
comment_form = CommentForm(request.POST)
if comment_form.is_valid():
new_comment = comment_form.save(commit=False)
new_comment.post = post
new_comment.name = request.user
new_comment.save()
else:
comment_form = CommentForm()
forms.py
class BlogPostForm(forms.ModelForm):
class Meta:
model = Blog
fields = ['title', 'slug', 'content', 'image', 'category', 'tags']
models.py
class Blog(models.Model):
title = models.CharField(max_length=10000, null=True, blank=True, verbose_name="Title")
content = models.TextField(verbose_name="Post Content")
slug = models.SlugField(unique=True)
image = models.ImageField(upload_to="blog-images/%Y/%m/%d/", verbose_name="Post Thumbnail")
category = models.ForeignKey(Category, on_delete=models.DO_NOTHING, verbose_name="Category", null=True)
tags = models.ManyToManyField(Tag, related_name='tags', verbose_name="Tag", null=True)
status = models.CharField(choices=STATUS_CHOICE, default="published", max_length=150, verbose_name='Status')
creator = models.ForeignKey(User, on_delete=models.DO_NOTHING, verbose_name="Creator", null=True)
created = models.DateTimeField(auto_now_add=True ,verbose_name="Created", null=True)
def get_absolute_url(self):
return reverse('blog:blog-details', args=[self.slug])
class Meta:
verbose_name = "Blog Post"
verbose_name_plural = "Blog Posts"
def __str__(self):
return self.title
urls.py
urlpatterns = [
path('', views.BlogList, name="home"),
path('post/<slug:blog_slug>', views.BlogDetail, name="blog-details"),
path('post/categories/<slug:category_slug>', views.category, name="category"),
path('post/tags/<slug:tag_slug>', views.tag, name="tags"),
path('post/create/', views.blogpost, name="add-post"),
bloghome.html
<!-- this would list out all the blog post -->
{% for post in posts %}
<div class="col-lg-4 col-md-6 col-sm-12">
<div class="articles_grid_style style-2">
<div class="articles_grid_thumb">
<a href="{{post.get_absolute_url}}"><img src="{{post.image.url}}" class="img-fluid" alt="" style="width: 450px; height: 250px;"></a>
</div>
<div class="articles_grid_caption">
<div class="mpd-date-wraps">
<!-- <span class="mpd-meta-date">10</span> -->
<span class="mpd-meta-month">{{post.created|date:"d, M Y"}}</span>
</div>
<div class="blog-grid-cat" style="background: rgb(161, 161, 161); color: white;">{{post.category}}</div>
<a href="{{post.get_absolute_url}}"><h4>{{post.title|truncatechars:70}}</h4></a>
<div class="articles_grid_desc">
<p style="color: black;">{{post.content|truncatechars:80}}</p>
</div>
</div>
<div class="articles_grid_caption-footer">
<div class="articles_grid_author">
<div class="articles_grid_author_img"><img src="{{post.creator.profile.image.url}}" class="img-fluid" alt=""></div>
<a href="">
<h4>{{post.creator.profile.first_name}} {{post.creator.profile.last_name}}</h4>
</a>
</div>
<div class="footer-flex-last">
<a href="{{post.get_absolute_url}}" class="bl-detail-view" style="background:linear-gradient(230deg, rgb(255, 0, 157) 0%, rgb(111, 0, 255) 100%), url(assets/img/tag-light.png) no-repeat; color: white;"><b>READ MORE</b></a>
</div>
</div>
</div>
</div>
{% endfor %}
addpost.html
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{form|crispy}}
<div class="form-group">
<button class="btn theme-bg rounded" type="submit">Send Message</button>
</div>
</form>
blogdetails.html
<div class="post-featured-img">
<img class="img-fluid" src="{{ post.image.url }}" alt="">
</div>
<div class="post-top-meta">
<ul class="meta-comment-tag">
<li><a href="#"><span class="icons"><i class="ti-user"></i></span>by {{ post.creator.profile.first_name }} {{ post.creator.profile.last_name }}</a></li>
<li><a href="#"><span class="icons"><i class="ti-comment-alt"></i></span>{{comments.count}} Comments</a></li>
</ul>
</div>
<h2 class="post-title">{{ post.title }}</h2>
<p style="color: black;">{{ post.content }}<p>
如果能看到您的模板代码会很有帮助,但这里有一些我看到的问题。
首先,您的 blogpost
观点。当您执行 POST 请求时,在保存表单并设置成功消息后,重定向到 BlogDetail
视图。按照您的编码方式,保存表单后它将再次呈现 blogpost
视图,这次是包含请求 POST 数据的表单。查找 redirect
here.
其次,在您的 BlogList
视图中,您正在 posts
查询集上调用 .values()
。没有看到您的模板代码,我无法判断这是否是故意的,但请确保您知道查询集中的 values()
return 是什么。您可能不想使用它。
第三,您的 BlogDetail
视图没有 return 任何东西,您需要 return HttpResponse 使用例如 render
就像您的其他视图一样。
最后要注意的是,它的通用约定是以小写形式命名基于函数的视图,其中 _ 为 space。 CamelCase 保留用于基于 class 的视图。