Проблемы с пользовательскими тегами Django - PullRequest
0 голосов
/ 24 сентября 2019

Hello Stack Overflow!

Я делаю новостной сайт в Django в рамках моей "стажировки", я только начал изучать веб-разработку.Мне было дано задание создать собственный шаблон (он должен быть пользовательским шаблоном), который будет выводить 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 %}

my views.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 "все статьи"страница:

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

Большое спасибо, что нашли время, чтобы прочитать это.Хорошего дня!

1 Ответ

0 голосов
/ 25 сентября 2019

Ваш измененный код не будет работать вообще на одной странице статьи;вы получите 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 %}
...