Python Django按类别筛选文章

Python Django按类别筛选文章,python,django,filter,categories,article,Python,Django,Filter,Categories,Article,我正在建立一个新闻网站,作为我被赋予的一项任务,家庭作业的一部分 我有一个“articles.html”模板,它按发布日期呈现我所有的新闻文章。 我在模板中添加了一个for循环,以循环类别模型并将类别显示为列表 我现在想做的是按类别过滤我的文章,所以当我点击列表上的“体育”时,我的网站现在只显示与体育相关的文章 我在网上读了很多东西,我只是感到困惑,我今天应该这么做,但我今天过得很艰难,希望能得到一些指导 以下是我的模型.py: from django.db import models from

我正在建立一个新闻网站,作为我被赋予的一项任务,家庭作业的一部分

我有一个“articles.html”模板,它按发布日期呈现我所有的新闻文章。 我在模板中添加了一个for循环,以循环类别模型并将类别显示为列表

我现在想做的是按类别过滤我的文章,所以当我点击列表上的“体育”时,我的网站现在只显示与体育相关的文章

我在网上读了很多东西,我只是感到困惑,我今天应该这么做,但我今天过得很艰难,希望能得到一些指导

以下是我的模型.py:

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
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 Category.objects.all()


def article(request, article_id):

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

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


class ArticlesView(generic.ListView):
    context_object_name = 'latest_article_list'
    template_name = 'news/articles.html'
    queryset = Article.objects.order_by("-pub_date")

    def get_context_data(self, **kwargs):
        context = super(ArticlesView, self).get_context_data(**kwargs)
        context['category'] = Category.objects.all()
        return 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 URL.py:

from django.urls import path, include

from . import views

app_name = "news"
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('<int:article_id>/', views.article, name='article'),
    path('articles/', views.ArticlesView.as_view(), name='articles'),
    path('search/', include('haystack.urls')),
    path('<int:pk>/comment/', views.add_comment_to_article, name='add_comment_to_post'),
    path('category/<int:category_id>', views.CategoryView.as_view(), name="category")
]

从django.url导入路径,包括
从…起导入视图
app_name=“新闻”
URL模式=[
路径(“”,views.IndexView.as_view(),name='index'),
路径(“/”,views.article,name='article'),
路径('articles/',views.ArticlesView.as_view(),name='articles'),
路径('search/',include('haystack.url')),
路径('/comment/',views.add_comment_to_article,name='add_comment_to_post'),
路径('category/',views.CategoryView.as_view(),name=“category”)
]
我试图在articles.html中呈现所有内容的模板:

<div class="container">
    {% block articles %}
    <!-- ***************************************** -->
    <ul>
        <li>Categories:</li>
        {% for category in category %}

        <li>
            <h1>{{ category.id}}</h1>
            <a href="#">{{ category.category_title }}</a>
        </li>

        {% endfor %}
    </ul>
    <!-- ***************************************** -->

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


{%block articles%}
  • 类别:
  • {类别%中的类别为%1}
  • {{category.id}
  • {%endfor%}

物品清单:
{最新文章列表%中文章的百分比}

{{article.author}

{{article.description}}

  • {{article.pub_date}
  • |
  • 2评论
  • |
  • |
{%endfor%}
为混乱的代码道歉,仍在努力学习

感谢您抽出时间阅读此文章


我不是要你为我做这件事,一个解释就足够了!谢谢

您可以通过传递筛选器参数来覆盖
ArticlesView
上的
get_queryset
方法,如下所示:

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

    def get_context_data(self, **kwargs):
        context = super(ArticlesView, self).get_context_data(**kwargs)
        # It would be best to rename the context to categories 
        # as you are returning multiple objects
        context['categories'] = Category.objects.all()
        return context

    def get_queryset(self):
        # Note you do not have to use the article PK you can use any
        # article field just update the template argument accordingly 
        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")
<ul>
    <li>Categories:</li>
    {% for category in categories %}

    <li>
        <h1>{{ category.id}}</h1>
        <a href="{% url 'news:articles' %}?pk={{category.id}}">{{ category.category_title }}</a>
    </li>

<ul>
然后,您可以在模板中更新类别链接,如下所示:

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

    def get_context_data(self, **kwargs):
        context = super(ArticlesView, self).get_context_data(**kwargs)
        # It would be best to rename the context to categories 
        # as you are returning multiple objects
        context['categories'] = Category.objects.all()
        return context

    def get_queryset(self):
        # Note you do not have to use the article PK you can use any
        # article field just update the template argument accordingly 
        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")
<ul>
    <li>Categories:</li>
    {% for category in categories %}

    <li>
        <h1>{{ category.id}}</h1>
        <a href="{% url 'news:articles' %}?pk={{category.id}}">{{ category.category_title }}</a>
    </li>

<ul>
  • 类别:
  • {categories%%中的类别为%s}
  • {{category.id}

请尝试一下,让我知道它是否在哪一类中起作用

您想筛选哪些文章?我相信,因为我需要文章信息来根据结果进行渲染?老实说,我并不完全确定。这是当我单击其中一个类别时得到的结果:ValueError at/news/articles/invalid literal for int(),以10为基数:“category.id”回溯说明:异常类型:NoReverseMatch at/news/articles/Exception Value:Reverse for'articles',关键字参数“{pk 2}”未找到。尝试了1个模式:['news\\/articles\\/$']从
文章
url中删除前导的
/
,然后重试:
路径('articles',views.ArticlesView.as_view(),name='articles')
仍然存在相同的错误:/news/articles处的值错误int()的文本无效以10为基数:“category.id”不知道可能出了什么问题。:/是不是说category.id不是整数?还是一样:/ValueError at/news/articles/$invalid literal for int(),以10为基数:'category.id'请求方法:获取请求URL:Django版本:2.1.8异常类型:ValueError异常值:无效literal for int(),以10为基数:'category.id'