【问题标题】:Django Custom Tag ProblemsDjango 自定义标签问题
【发布时间】:2020-01-24 17:04:24
【问题描述】:

你好堆栈溢出!

作为“实习”的一部分,我正在 Django 中创建一个新闻网站,我刚刚开始学习 Web 开发。我的任务是制作一个自定义模板(它必须是一个自定义模板),它将呈现一个类别中的 3 条最新消息,我必须将它作为侧边栏包含在我的“文章”页面上。

我尝试编写自定义标签,但不幸的是它并不顺利。这是我在网站上的“最后”任务,我被卡住了(就像之前很多次一样:P)

事情就是这样..如果我在“列出所有文章”页面上包含自定义标签,一切正常,它会根据我点击的类别正确呈现。

问题是,一旦我尝试将我的标签包含到我的“单篇文章”页面中,我就碰壁了。该标签仍在工作,但现在显示我的所有文章,而不是过滤与该文章类别相关的文章。

简单来说,如果我点击“健康”文章打开它,我希望侧边栏只包含“健康”类别的文章,我希望这是有道理的。

有几分钟空闲时间愿意帮助我的人吗? :)

我的代码:

自定义标签:

from django import template
from news.models import Article

register = template.Library()


@register.inclusion_tag("news/categories.html")
def show_results(article):
    article = article.filter()[:3]
    return {'article': article}

标签的HTML模板:

{% load article_extras %}
<div class="articles-filter">
    <ul>
        {% for a in article %}
        <img src="{{ a.article_image.url }}" alt="">
        <h5>{{ a.title }}</h5>
        {% endfor %}
    </ul>

</div>

我的模型:

from django.db import models
from datetime import datetime
from autoslug import AutoSlugField


class Category(models.Model):
    category_title = models.CharField(max_length=200, default="")

    def __str__(self):
        return self.category_title


class Article(models.Model):
    title = models.CharField('title', max_length=200, blank=True)
    slug = AutoSlugField(populate_from='title', default="",
                         always_update=True, unique=True)
    author = models.CharField('Author', max_length=200, default="")
    description = models.TextField('Description', default="")
    is_published = models.BooleanField(default=False)
    article_text = models.TextField('Article text', default="")
    pub_date = models.DateTimeField(default=datetime.now, blank=True)
    article_image = models.ImageField('Article Image')
    article_category = models.ForeignKey(Category, on_delete="models.CASCADE", default="")
    img2 = models.ImageField('Article Image 2', default="", blank=True)
    img3 = models.ImageField('Article Image 3', default="", blank=True)
    img4 = models.ImageField('Article Image 4', default="", blank=True)
    img5 = models.ImageField('Article Image 5', default="", blank=True)
    img6 = models.ImageField('Article Image 6', default="", blank=True)

    def __str__(self):
        return self.title


class Comment(models.Model):
    post = models.ForeignKey('Article', on_delete=models.CASCADE, related_name='comments')
    author = models.CharField(max_length=200)
    text = models.TextField()
    created_date = models.DateTimeField(default=datetime.now, blank=True)
    approved_comment = models.BooleanField(default=False)

    def approve(self):
        self.approved_comment = True
        self.save()

    def __str__(self):
        return self.text

我试图在其中包含我的自定义标签的“单篇文章”模板:

{% extends "news-base.html" %}

{% load static %}
{% load article_extras %}


{% block article %}

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>





<div class="preloader d-flex align-items-center justify-content-center">
  <div class="spinner">
    <div class="double-bounce1"></div>
    <div class="double-bounce2"></div>
  </div>
</div>
{% show_results article %}
<!-- ##### Post Details Area Start ##### -->
<section class="container post-details-area">
  <div class="container single-article-div">
    <hr class="hr-single">
    <h2 class="single-article-titles">{{ article.title }}</h2>
    <hr class="hr-single">
    <img class="single-article-img" src="{{ article.article_image.url }}" alt="">
    <!-- *********************************** -->
    <hr class="hr-single">
    <p>Category: {{ article.article_category }}</p>
    <hr class="hr-single">
    <div class="row justify-content-center">
      <!-- Post Details Content Area -->
      <div class="col-12 col-xl-8">
        <div class="post-details-content bg-white box-shadow">
          <div class="blog-thumb">

          </div>
          <div class="blog-content">
            <div class="post-meta">
              <a href="#">{{ article.pub_date }}</a>
            </div>
            <h3 class="single-article-titles post-title"> {{ article.description }}</h3>
            <hr>

            <!-- Post Meta -->
            <div class="post-meta-2">
              <a href="#"><i class="fa fa-eye" aria-hidden="true"></i> 1034</a>
              <a href="#"><i class="fa fa-thumbs-o-up" aria-hidden="true"></i> 834</a>
              <a href="#"><i class="fa fa-comments-o" aria-hidden="true"></i> 234</a>
            </div>
            <p>{{ article.article_text }}</p>
            <hr />

            {% include "partials/_thumbnails.html" %}

            <hr>
            <p>Author: {{ article.author }}</p>

            <hr>

            {% for comment in article.comments.all %}
            <div class="comment">
              <div class="date">{{ comment.created_date }}</div>
              <strong>{{ comment.author }}</strong>
              <p>{{ comment.text|linebreaks }}</p>
            </div>
            {% empty %}
            <p>No comments here yet :(</p>
            {% endfor %}
          </div>
          <!-- Post A Comment Area -->
          <div class="post-a-comment-area bg-white mb-30 p-30 box-shadow clearfix">
            <!-- Section Title -->
            <div class="section-heading">
              <h5>LEAVE A REPLY</h5>
            </div>
            <!-- Reply Form -->
            <div class="contact-form-area">
              <form action="#" method="post">
                <div class="row">
                  <div class="col-12 col-lg-6">
                    <input type="text" class="form-control comment-section" id="name" placeholder="Your Name*"
                      required />
                  </div>
                  <div class="col-12 col-lg-6">
                    <input type="email" class="form-control comment-section" id="email" placeholder="Your Email*"
                      required />
                  </div>
                  <div class="col-12">
                    <textarea name="message" class="form-control" id="message" cols="30" rows="10"
                      placeholder="Message*" required></textarea>
                  </div>
                  <div class="col-12">
                    <button class="btn mag-btn comment-section" type="submit">
                      Submit Comment
                    </button>
                  </div>
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>


{% endblock %}

我的意见.py:

from django.shortcuts import render, reverse, get_object_or_404
from django.views import generic
from news.models import Article, Category
from .forms import CommentForm
from django.http import HttpResponseRedirect


class IndexView(generic.ListView):

    template_name = 'news/index.html'
    context_object_name = 'latest_article_list'

    def get_queryset(self):
        return Article.objects.order_by("-pub_date").filter(is_published=True)[:6]


class CategoryView(generic.ListView):

    template_name = 'news/categories.html'
    context_object_name = 'category'

    def get_queryset(self):
        return Article.objects.filter(article_category__category_title="Politics")


class ArticlesView(generic.ListView):
    context_object_name = 'latest_article_list'
    template_name = 'news/articles.html'
    paginate_by = 5

    def get_context_data(self, **kwargs):
        context = super(ArticlesView, self).get_context_data(**kwargs)
        context['categories'] = Category.objects.all()
        return context

    def get_queryset(self):
        category_pk = self.request.GET.get('pk', None)
        if category_pk:
            return Article.objects.filter(article_category__pk=category_pk).order_by("-pub_date")
        return Article.objects.order_by("-pub_date")


def article(request, article_id):

    article = get_object_or_404(Article, pk=article_id)
    context = {'article': article}

    return render(request, 'news/article.html', context)


def add_comment_to_article(request, pk):
    article = get_object_or_404(Article, pk=pk)
    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = article
            comment.save()
            return HttpResponseRedirect(reverse('news:article', kwargs={"article_id": article.pk}))
    else:
        form = CommentForm()
    return render(request, 'news/add_comment_to_article.html', {'form': form})

我的“所有文章”页面:

<div class="container">
    {% block articles %}

    <!-- ***************************************** -->
    <div class="category-filter container">
        <ul>
            <li class="categories-title">Categories:</li>
            <hr class="small-line">
            {% for category in categories %}

            <li class="category-list">
                <a href="{% url 'news:articles' %}?pk={{category.id}}">{{ category.category_title }}</a>
            </li>
            {% endfor %}
        </ul>
    </div>
    <!-- ***************************************** -->
    {% show_results latest_article_list %}

    <hr class="hr-style1">
    <h2 class="article-list-title">Article List :</h2>
    <hr class="hr-style2">
    <div class="container list-wrapper">

        {% for article in latest_article_list %}

        <div class="container">
            <div class="well">
                <div class="media">
                    <a class="pull-left" href="{% url 'news:article' article.id %}">
                        <img class="media-object" src="{{ article.article_image.url }}">
                    </a>
                    <div class="media-body">
                        <h4 class="media-heading"><a href="{% url 'news:article' article.id %}">{{ article.title }}</a>
                        </h4>
                        <p class="text-right">{{ article.author }}</p>
                        <p>{{ article.description }}</p>
                        <ul class="list-inline list-unstyled">
                            <li><span><i class="glyphicon glyphicon-calendar"></i> {{ article.pub_date }}
                                </span></li>
                            <li>|</li>
                            <span><i class="glyphicon glyphicon-comment"></i> 2 comments</span>
                            <li>|</li>
                            <li>
                                <span class="glyphicon glyphicon-star"></span>
                                <span class="glyphicon glyphicon-star"></span>
                                <span class="glyphicon glyphicon-star"></span>
                                <span class="glyphicon glyphicon-star"></span>
                                <span class="glyphicon glyphicon-star-empty"></span>
                            </li>
                            <li>|</li>
                            <li>
                                <span><i class="fa fa-facebook-square"></i></span>
                                <span><i class="fa fa-twitter-square"></i></span>
                                <span><i class="fa fa-google-plus-square"></i></span>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </div>
    {% endfor %}

非常感谢您花时间阅读本文。 祝你有美好的一天!

【问题讨论】:

  • 你的问题很奇怪。您根本没有做任何事情来将标签中的查询限制为仅三篇文章,也没有按类别过滤它。你为什么认为它会那样做?
  • 哦,我的错,那是我的旧代码。我想问的是,是否有人可以向我解释这实际上是如何完成的。我确实尝试使用 [:3] 将其限制为 3,这是可行的,排序也适用于 sort_by()。我的问题是它呈现不同的结果取决于它是在“文章”页面还是“所有文章”页面上,我试图理解为什么以及如何。基本上,我需要出现在我的“单篇文章”页面上的“所有文章”页面上的结果。对此感到抱歉,如果这令人困惑,也很抱歉,到目前为止,我度过了最长的一周。谢谢!
  • 好吧,就像我说的那样,该标签中也没有按类别过滤的内容。它不适用于任何页面。请显示两个页面的视图以及 all_articles 页面的模板。
  • 是的,你完全正确。我把它改成了我摆弄它之前的样子,现在它可以在“所有文章”页面上工作,但仍然不能在我需要它的“单篇文章”页面上工作。我将视图和模板添加到我的原始帖子中:)

标签: python django templates tags categories


【解决方案1】:

您更改的代码在单个文章页面上根本不起作用;你会得到一个 AttributeError。

问题是您在列表视图中传递了查询集latest_article_list,但在单篇文章视图中您传递的是那篇文章。您不能过滤文章,只能过滤查询集。

确实,您似乎想要做的是传递一个类别。没有理由将最新文章列表传递给该模板标签;您可以直接在标签中获取文章。但是从单个文章视图中,您希望获得具有相同类别的文章。因此,将参数设为category,并将其设为可选。

@register.inclusion_tag("news/categories.html")
def show_results(category=None):
    articles = Article.objects.all()
    if category:
        articles = articles.filter(category=category)
    return {'article': article[:3]}

现在从列表视图中您可以只调用不带参数的标签:

{% show_results %}

而从单一视图中您可以传递文章类别:

{% show_results article.category %}

【讨论】:

  • 谢谢丹尼尔!我让它在单篇文章页面上呈现!现在我要做的就是弄清楚如何正确过滤所有内容,因为现在它正在显示所有类别的最新文章,我需要它来显示与我单击的单个文章相关的类别。再一次,非常感谢您的帮助,您为我做了一些事情,我真的很感激!
猜你喜欢
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-07
  • 1970-01-01
  • 2010-10-10
  • 2011-07-11
相关资源
最近更新 更多