无法将关键字 'tag' 解析为字段
Cannot resolve keyword 'tag' into field
我正在关注这本书 'Django 2 by example',当涉及到为博客 posts 实施标签系统时,我遇到了这个错误:
错误是在我点击此处显示的第一个post标签时引起的
这里是models.py
from django.contrib.auth.models import User
from django.db import models
from django.utils import timezone
from django.urls import reverse
from taggit.managers import TaggableManager
class PublishManager(models.Manager):
def get_queryset(self):
return super(PublishManager, self).get_queryset().filter(status='published')
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
)
title = models.CharField(max_length=250)
slug = models.SlugField(max_length=250, unique_for_date='publish')
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_post')
body = models.TextField()
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')
object = models.Manager() # The default manager.
published = PublishManager() # My custom manager
tags = TaggableManager() # Imported from the library 'taggit'
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse(
'blog:post_detail',
args=[
self.publish.year,
self.publish.month,
self.publish.day,
self.slug,
]
)
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
name = models.CharField(max_length=80)
email = models.EmailField()
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
class Meta:
ordering = ('created',)
def __str__(self):
return 'Comment by {} on {}'.format(self.name, self.post)
list.html
{% extends 'base.html' %}
{% block content %}
<h1>My Blog</h1>
{% if tag %}
<h2>Posts tagged with "{{ tag.name }}"</h2>
{% endif %}
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="tags">
Tags:
{% for tag in post.tags.all %}
<a href="{% url 'blog:post_list_by_tag' tag.slug %}">
{{ tag.name }}
</a>
{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
<!--{% include "pagination.html" with page=page_obj %}-->
<!-- ^^^^^^^^^^^^ if using class-based view page=page_obj ^^^^^^^^^^ -->
{% include "pagination.html" with page=posts %}
<!-- ^^^^^^^^^^^^ if using function-based view page=posts ^^^^^^^^^^ -->
{% endblock %}
和urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.post_list, name='post_list'),
# path('', views.PostListView.as_view(), name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail'),
path('<int:post_id>/share/', views.post_share, name='post_share'),
path('tag/?<slug:tag_slug>/', views.post_list, name='post_list_by_tag'),
]
views.py
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.shortcuts import render, get_object_or_404
from .models import Post
from django.views.generic import ListView
from .forms import EmailPostForm, CommentForm
from django.core.mail import send_mail
from taggit.models import Tag
def post_list(request, tag_slug=None):
object_list = Post.published.all()
tag = None
if tag_slug:
tag = get_object_or_404(Tag, slug=tag_slug)
object_list = object_list.filter(tag__in=[tag])
paginator = Paginator(object_list, 3)
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# if page is not an integer deliver the first page
posts = paginator.page(1)
except EmptyPage:
# if page is out of range deliver last page of results
posts = paginator.page(paginator.num_pages)
return render(request, 'blog/post/list.html', {
'posts': posts,
'page': page,
'tag': tag,
})
# ^^^^^^^^^^^^^^^^^^ SAME AS ^^^^^^^^^^^^^^^^^^^^^^^^ #
# class PostListView(ListView):
# queryset = Post.published.all()
# context_object_name = 'posts'
# paginate_by = 3
# template_name = 'blog/post/list.html'
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)
# List of active comments for this post
comments = post.comments.filter(active=True)
new_comment = None
if request.method == 'POST':
# A comment was posted
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
# Create Comment objects but don't save to database yet
new_comment = comment_form.save(commit=False)
# Assign the current post to the comment
new_comment.post = post
# Save
new_comment.save()
else:
comment_form = CommentForm()
return render(request, 'blog/post/detail.html', {'post': post,
'comments': comments,
'new_comment': new_comment,
'comment_form': comment_form})
def post_share(request, post_id):
# Retrieve post by id
post = get_object_or_404(Post,
id=post_id,
status='published')
sent = False
if request.method == 'POST':
# Form was submitted
form = EmailPostForm(request.POST)
if form.is_valid():
# Form fields passed validation
cd = form.cleaned_data
post_url = request.build_absolute_uri(post.get_absolute_url())
subject = '{} ({}) recommends you reading "{}"'.format(cd['name'], cd['email'], post.title)
message = 'Read "{}" at {}\n\n{}\'s comments: {}'.format(post.title, post_url, cd['name'], cd['comments'])
send_mail(subject, message, 'admin@mayblog.com', [cd['to']])
sent = True
else:
form = EmailPostForm()
return render(request, 'blog/post/share.html', {'post': post, 'form': form, 'sent': sent})
如果您需要上传任何其他代码,请告诉我。
希望这是一些易于修复的错误。
感谢您的帮助。
在post_list
视图中,您需要将object_list = object_list.filter(tag__in=[tag])
更改为
object_list = object_list.filter(tags__in=[tag])
我正在关注这本书 'Django 2 by example',当涉及到为博客 posts 实施标签系统时,我遇到了这个错误:
错误是在我点击此处显示的第一个post标签时引起的
这里是models.py
from django.contrib.auth.models import User
from django.db import models
from django.utils import timezone
from django.urls import reverse
from taggit.managers import TaggableManager
class PublishManager(models.Manager):
def get_queryset(self):
return super(PublishManager, self).get_queryset().filter(status='published')
class Post(models.Model):
STATUS_CHOICES = (
('draft', 'Draft'),
('published', 'Published'),
)
title = models.CharField(max_length=250)
slug = models.SlugField(max_length=250, unique_for_date='publish')
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_post')
body = models.TextField()
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')
object = models.Manager() # The default manager.
published = PublishManager() # My custom manager
tags = TaggableManager() # Imported from the library 'taggit'
class Meta:
ordering = ('-publish',)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse(
'blog:post_detail',
args=[
self.publish.year,
self.publish.month,
self.publish.day,
self.slug,
]
)
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
name = models.CharField(max_length=80)
email = models.EmailField()
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
class Meta:
ordering = ('created',)
def __str__(self):
return 'Comment by {} on {}'.format(self.name, self.post)
list.html
{% extends 'base.html' %}
{% block content %}
<h1>My Blog</h1>
{% if tag %}
<h2>Posts tagged with "{{ tag.name }}"</h2>
{% endif %}
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="tags">
Tags:
{% for tag in post.tags.all %}
<a href="{% url 'blog:post_list_by_tag' tag.slug %}">
{{ tag.name }}
</a>
{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
<!--{% include "pagination.html" with page=page_obj %}-->
<!-- ^^^^^^^^^^^^ if using class-based view page=page_obj ^^^^^^^^^^ -->
{% include "pagination.html" with page=posts %}
<!-- ^^^^^^^^^^^^ if using function-based view page=posts ^^^^^^^^^^ -->
{% endblock %}
和urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.post_list, name='post_list'),
# path('', views.PostListView.as_view(), name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail'),
path('<int:post_id>/share/', views.post_share, name='post_share'),
path('tag/?<slug:tag_slug>/', views.post_list, name='post_list_by_tag'),
]
views.py
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.shortcuts import render, get_object_or_404
from .models import Post
from django.views.generic import ListView
from .forms import EmailPostForm, CommentForm
from django.core.mail import send_mail
from taggit.models import Tag
def post_list(request, tag_slug=None):
object_list = Post.published.all()
tag = None
if tag_slug:
tag = get_object_or_404(Tag, slug=tag_slug)
object_list = object_list.filter(tag__in=[tag])
paginator = Paginator(object_list, 3)
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# if page is not an integer deliver the first page
posts = paginator.page(1)
except EmptyPage:
# if page is out of range deliver last page of results
posts = paginator.page(paginator.num_pages)
return render(request, 'blog/post/list.html', {
'posts': posts,
'page': page,
'tag': tag,
})
# ^^^^^^^^^^^^^^^^^^ SAME AS ^^^^^^^^^^^^^^^^^^^^^^^^ #
# class PostListView(ListView):
# queryset = Post.published.all()
# context_object_name = 'posts'
# paginate_by = 3
# template_name = 'blog/post/list.html'
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)
# List of active comments for this post
comments = post.comments.filter(active=True)
new_comment = None
if request.method == 'POST':
# A comment was posted
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
# Create Comment objects but don't save to database yet
new_comment = comment_form.save(commit=False)
# Assign the current post to the comment
new_comment.post = post
# Save
new_comment.save()
else:
comment_form = CommentForm()
return render(request, 'blog/post/detail.html', {'post': post,
'comments': comments,
'new_comment': new_comment,
'comment_form': comment_form})
def post_share(request, post_id):
# Retrieve post by id
post = get_object_or_404(Post,
id=post_id,
status='published')
sent = False
if request.method == 'POST':
# Form was submitted
form = EmailPostForm(request.POST)
if form.is_valid():
# Form fields passed validation
cd = form.cleaned_data
post_url = request.build_absolute_uri(post.get_absolute_url())
subject = '{} ({}) recommends you reading "{}"'.format(cd['name'], cd['email'], post.title)
message = 'Read "{}" at {}\n\n{}\'s comments: {}'.format(post.title, post_url, cd['name'], cd['comments'])
send_mail(subject, message, 'admin@mayblog.com', [cd['to']])
sent = True
else:
form = EmailPostForm()
return render(request, 'blog/post/share.html', {'post': post, 'form': form, 'sent': sent})
如果您需要上传任何其他代码,请告诉我。 希望这是一些易于修复的错误。
感谢您的帮助。
在post_list
视图中,您需要将object_list = object_list.filter(tag__in=[tag])
更改为
object_list = object_list.filter(tags__in=[tag])