简体   繁体   English

Django 自定义标签问题

[英]Django Custom Tag Problems

Hello Stack Overflow !你好堆栈溢出!

I am making a news site in Django as a part of my "internship", I have just started learning web development.作为我“实习”的一部分,我正在 Django 制作一个新闻网站,我刚刚开始学习 web 开发。 I was given a task to make a custom template ( it HAS to be a custom template ) which will render out 3 latest news from a category, and I have to include it as a sidebar on my "article" page.我的任务是制作一个自定义模板(它必须是一个自定义模板),它将呈现一个类别中的 3 条最新新闻,我必须将它作为侧边栏包含在我的“文章”页面上。

I tried to write the custom tag, but it's not going to well unfortunately.我尝试编写自定义标签,但不幸的是它并不顺利。 This is my "last" task for the website, and I'm stuck (like many times before:P )这是我在网站上的“最后”任务,我被卡住了(就像之前很多次一样:P)

Here's the thing..everything is working if I include the custom tag on my "list all articles" page, it renders correctly depending on which category I click on.事情是这样的……如果我在“列出所有文章”页面上包含自定义标签,一切正常,它会根据我点击的类别正确呈现。

The thing is, once I try to include my tag into my "single article" page I hit a brick wall.问题是,一旦我尝试将我的标签包含到我的“单篇文章”页面中,我就碰壁了。 The tag is still working, but is now displaying all of my articles, instead of filtering the articles related to that article's category.该标签仍在工作,但现在显示我的所有文章,而不是过滤与该文章类别相关的文章。

To simplyfiy, If i click on a "health" article to open it, I want the sidebar just to include the articles for the "health" category, I hope that makes sense.简单来说,如果我单击“健康”文章将其打开,我希望侧边栏仅包含“健康”类别的文章,我希望这是有道理的。

Anyone with a couple of minutes of spare time willing to help me out?有几分钟空闲时间愿意帮助我的人吗? :) :)

My code:我的代码:

the custom tag:自定义标签:

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 template for the tag:标签的 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>

my models:我的模型:

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

the "single article" template where I am trying to include my custom tag:我试图在其中包含我的自定义标签的“单篇文章”模板:

{% 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 %}

my views.py:我的意见.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})

my "all articles" page:我的“所有文章”页面:

<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 %}

Thank you so much for taking the time to read this.非常感谢您花时间阅读本文。 Have a good day !祝你有美好的一天 !

Your changed code wouldn't work at all on the single article page;您更改的代码在单个文章页面上根本不起作用; you would get an AttributeError.你会得到一个 AttributeError。

The problem is that you are in your list view you are passing the queryset, latest_article_list , but in the single article view you are passing that single article.问题是您在列表视图中传递了latest_article_list ,但在单篇文章视图中您传递的是那篇文章。 You can't filter an article, you can only filter a queryset.您无法过滤文章,只能过滤查询集。

Really it seems that the thing you want to do is to pass a category.确实,您想要做的事情似乎是通过一个类别。 There's no reason to pass the latest article list to that template tag;没有理由将最新文章列表传递给该模板标签; you can just get the articles directly in the tag.您可以直接在标签中获取文章。 But from the single article view you want to get the articles with the same category.但是从单个文章视图中,您希望获得具有相同类别的文章。 So, make the parameter category , and make it optional.因此,将参数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]}

Now from the list view you can just call the tag without arguments:现在从列表视图中,您可以只调用不带 arguments 的标签:

{% show_results %}

whereas from the single view you can pass the article category:而从单一视图中,您可以传递文章类别:

{% show_results article.category %}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM