为什么在 django 3 中使用 taggit 运行显示类似帖子的代码时出错?

问题描述 投票:0回答:1

我目前正在通过 antonio mele 的《Django 示例》一书学习 Django,并且已经到了如何使用标签显示相同帖子的阶段。

感觉自己已经很好的按照书上的内容做了,但是还是卡在这里 Error in web browser

它发生在我编写的代码中:

在 models.py 中编码

from django.db import models

# Create your models here.
from django.utils import timezone
from django.contrib.auth.models import User
from django.urls import reverse
from taggit.managers import TaggableManager

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)
    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')

    objects = models.Manager()
    published = PublishedManager()
    tags = TaggableManager()

    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 f'Comment by {self.name} on {self.post}'


Views.py

from django.db.models import Count
from django.shortcuts import render, get_object_or_404
from django.core.paginator import Paginator, EmptyPage, \
                                    PageNotAnInteger
from django.views.generic import ListView
from django.core.mail import send_mail
from .models import Post, Comment
from .forms import EmailPostForm, CommentForm
from taggit.models import Tag

# Create your views here.
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(tags__in=[tag])

    paginator = Paginator(object_list, 3) 
    page = request.GET.get('page')
    try:
        posts = paginator.page(page)
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)
    return render(request, 
                    'blog/post/list.html', 
                    {'page' : page, 
                    'posts' : posts, 
                    'tag': tag})

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)

    # Menampilkan comment yang aktif di postingan ini
    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():
            #buat objek comment tapi gak di simpan
            new_comment = comment_form.save(commit=False)
            
            # kasih tahu kalau postingan sekarang lg di comment
            new_comment.post = post

            # simpan comment di database
            new_comment.save()
    else:
        comment_form = CommentForm()

    # daftar postingan yang mirip
    post_tags_ids = post.tags.values_list('id', flat=True)
    similar_posts = Post.published.filter(tags__in=post_tags_ids)\
                                  .exclude(id=post.id)
    similar_posts = similar_posts.annotate(same_tags=Count('tags'))\
                                .order_by('-same_tags','-publish')[:4]

    return render(request, 
                    'blog/post/detail.html', 
                    {'post' : post, 
                    'comments': comments, 
                    'new_comment': new_comment,
                    'comment_form': comment_form, 
                    'similar_posts': similar_posts})

def post_share(request, post_id):
    # retrieve post id
    post = get_object_or_404(Post, id = post_id, status = 'published')
    sent = False

    if request.method == 'POST':
        form = EmailPostForm(request.POST)
        if form.is_valid():
            # Form fill isi nya udah bener
            cd = form.cleaned_data
            post_url = request.build_absolute_uri(
                post.get_absolute_url()
            )
            subject = f"{cd['name']} recommendeds you read " \
                      f"{post.title}"
            message = f"Read {post.title} at {post_url}\n\n" \
                      f"{cd['name']}\'s comments: {cd['comments']}"
            send_mail(subject, message, '[email protected]', [cd['to']])
            sent = True
    else:
        form = EmailPostForm()
    return render(request, 'blog/post/share.html', {'post': post,
                                                    'form': form, 
                                                    'sent': sent})

                                

细节.html

{% extends "blog/base.html" %}
{% block title %}{{ post.title }}{% endblock %}

{% block content %}
    <h1>{{ post.title }}</h1>
    <p class="date">
        Published {{ post.publish }} by {{ post.author }}
    </p>
    {{ post.body|linebreaks }}
    <p>
        <a href="{% url "blog:post_share" post.id %}">
            Share this post.
        </a>
    </p>
    <h2>Similar posts</h2>
    {% for post in similar_posts %}
        <p>
            <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
        </p>
    {% empty %}
        Gak ada postingan yang mirip
    {% endfor %}

    {%  with comments.count as total_comments %}
    <h2>
        {{ total_comments }} comment {{ total_comments|pluralize }}
    </h2>
    {% endwith %}

    {% for comment in comments %}
        <div class="comment">
            <p class="info">
                Comment {{ forloop.counter }} by {{ comment.name }}
                {{ comment.created }}
            </p>
            {{ comment.body|linebreaks }}

        </div>
    {% empty %}
        <p>There are no comments yet.</p>
    {% endfor %}
    
    {% if new_comment %}
        <h2>Your comment has been added</h2>
    {% else %}
        <h2>Add a new comment</h2>
        <form method="post">
            {{ comment_form.as_p }}
            {% csrf_token %}
            <p>
                <input type="submit" value="Add Comment">
            </p>
        </form>
    {% endif %}
{% endblock %}

我真的不知道我应该改什么,因为我觉得是按照书上的写的。所以,请各位知道这行代码有什么问题的朋友帮忙

谢谢

django post blogs django-taggit
1个回答
0
投票

blog
应用程序的
Post
模型的表名称:
blog_post
和相关字段
author
related_name='blog_post'
之间存在名称冲突,因为您忘记使用复数形式(在
blog_post之后缺少's'字母
).固定
Post
模型:

class Post(models.Model):
    ... 
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts')

检查您的数据库

blog_post
表是否有
tags
字段。如果没有,您可以重新运行迁移,或者由于您正在学习 Django,您可以从一个新的数据库开始。

© www.soinside.com 2019 - 2024. All rights reserved.