Django 按类别过滤文章
Django Filtering Articles by Categories
我正在建立一个新闻网站,作为我布置的任务的一部分,家庭作业。
我有一个 "articles.html" 模板,它按发布日期呈现我所有的新闻文章。
我在模板中添加了一个 for 循环来遍历类别模型并将类别显示为列表。
我现在想做的是按类别过滤我的文章,所以当我点击列表中的 "sports" 时,我的网站现在只显示与体育相关的文章。
我在网上看了这么多,我只是感到困惑,我今天应该这样做,但我今天过得很艰难,希望得到一些指导!
这是我的 models.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
我的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})
我的 urls.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")
]
我正在尝试渲染所有内容的模板,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 %}
抱歉代码乱七八糟,还在努力学习中。
感谢您花时间阅读本文!
我不是要你为我做这件事,一个解释就足够了!谢谢!
您可以通过传递过滤器参数来覆盖 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>
{% endfor %}
<ul>
试一试,如果有效请告诉我
我正在建立一个新闻网站,作为我布置的任务的一部分,家庭作业。
我有一个 "articles.html" 模板,它按发布日期呈现我所有的新闻文章。 我在模板中添加了一个 for 循环来遍历类别模型并将类别显示为列表。
我现在想做的是按类别过滤我的文章,所以当我点击列表中的 "sports" 时,我的网站现在只显示与体育相关的文章。
我在网上看了这么多,我只是感到困惑,我今天应该这样做,但我今天过得很艰难,希望得到一些指导!
这是我的 models.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
我的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})
我的 urls.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")
]
我正在尝试渲染所有内容的模板,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 %}
抱歉代码乱七八糟,还在努力学习中。
感谢您花时间阅读本文!
我不是要你为我做这件事,一个解释就足够了!谢谢!
您可以通过传递过滤器参数来覆盖 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>
{% endfor %}
<ul>
试一试,如果有效请告诉我