class=”markdown_views prism-atom-one-dark”>
Video link: 15. Up and down blogs and classification by month
filter filter condition
filter() returns a QuerySet.
- Equal to: direct filter
- Greater than: __gt
- Greater than or equal to: __gte
- Less than: __it
- Less than or equal to: __ite
- Contains: __contains
- Contains (ignore case): __icontains (SQLite does not support case sensitivity)
- begins with: __startswith
- Ends with: __endswith
- One of: __in
- Range: __range
Add “previous article” and “next article”, modify blog/view.py:
...
def blog_detail (request, blog_pk):
blog = get_object_or_404(Blog, pk=blog_pk)
context = {}
context['blog'] = blog
context['previous_blog'] = Blog.objects.filter(created_time__gt=blog.created_time).last()
context['next_blog'] = Blog.objects.filter(created_time__lt=blog.created_time).first()
return render_to_response('blog/blog_detail.html', context)
...
last() gets the last item queried; first() gets the first item queried.
Modify blog/templates/blog/blog_detail.html:
...
{% block content %}
<div class="container">
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<h3{
{ blog.title }}</h3
<ul class="blog-info-description">
<liAuthor: {
{ blog.author }}</li
<li
Classification: <a href='{% url'blogs_with_type' blog.blog_type.pk %} '>{
{ blog.blog_type }}</a
</li
<liDate published: {
{ blog.created_time|date:"Y-m-d H:n:s" }}</li>
</ul
<div class="blog-content">{
{ blog.content }}</div
<div class="blog-more">
<p
Previous:
{% if previous_blog %}
<a href="{% url 'blog_detail' previous_blog.pk %}">{
{ previous_blog.title }}</a
{% else %}
there is none left
{% endif %}
</p>
<p
Next:
{% if next_blog %}
<a href="{% url 'blog_detail' next_blog.pk %}"{
{ next_blog.title }}</a
{% else %}
there is none left
{% endif %}
</p
</div
</div
</div
</div
{% endblock %}
Modify blog/static/blog/blog.css:
...
div.blog-more {
margin-top: 1em;
}
exclude exclusion criteria
The usage is the same as filter(), and also returns QuerySet. For example, if pk is not equal to 3:
Blog.objects.exclude(pk=3)
Double underline in condition
- Field query type: For example, filter() cannot directly use operators such as “>=”, and needs to be replaced by something, such as “__gt=” means greater than.
- Foreign key expansion: For example, blogs_with_type() in blog/views.py can be changed to:
...
def blogs_with_type (request, blog_type_pk):
blog_type = get_object_or_404(BlogType, pk=blog_type_pk)
blogs_all_list = Blog.objects.filter(blog_type__id=blog_type_pk)
...
- Date expansion; for example, to query for blog posts created in 2017:
-
Blog.objects.filter(created_time__year=2017)
- Support chain query
-
Classify by month
Modify blog/views.py:
... def blogs_with_date (request, year, month): blogs_all_list = Blog.objects.filter(created_time__year=year, created_time__month=month) # Get blog posts that meet the requirements of year and month paginator = Paginator(blogs_all_list, settings. BLOGS_NUM_PER_PAGE) page_num = request.GET.get('page', 1) # Get the page number parameter of the url. GET returns a dictionary, page_num defaults to 1 page_of_blogs = paginator. get_page(page_num) current_page_num = page_of_blogs.number # Get the current page number # Get the pages before and after page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + list(range (current_page_num, min(current_page_num + 2, paginator.num_pages) + 1)) # add ellipsis if page_range[0] - 1 > = 2: page_range.insert(0, '...') if paginator.num_pages - page_range[-1] >= 2: page_range.append('...') # Add the first and last page numbers if page_range[0] != 1 : page_range.insert(0, 1) if page_range[-1] != paginator.num_pages: page_range.append(paginator.num_pages) context = {} context['page_of_blogs'] = page_of_blogs context['blog_types'] = BlogType.objects.all() context['page_range'] = page_range context['blog_dates'] = Blog.objects.dates('created_time', 'month', order='DESC') # created_time descending order by month span> context['blogs_with_date'] = "%s year %s month" % (year, month) return render_to_response('blog/blogs_with_date.html', context) ...
New blog/templates/blogs_with_date.html:
{% extends ' blog/blog_list.html'%} {% block title %} { { blog_type.type_name }} {% endblock%} {% block nav_blog_active %} active {% endblock %} {% block blog_list_title %} date archived: { { blogs_with_date }} <a href="{% url 'blog_list' %}"View all blog posts</a> {% endblock %}
Modify blog/urls.py:
from django.urls import path from . import views urlpatterns = [ path('', views.blog_list, name='blog_list'), path('', views.blog_detail, name='blog_detail'), path('type/', views.blogs_with_type, name='blogs_with_type') , path('date//', views.blogs_with_date, name='blogs_with_date '), ]
Modify blog/templates/blog_list.html:
... <div class="hidden-xs col-sm-4 col-md-3 col-lg-2"> <div class="panel panel-default"> <div class="panel-heading">Blog Category</div <div class="panel-body"> <ul class="blog-types"> {% for blog_type in blog_types %} <li <a href="{% url 'blogs_with_type' blog_type.pk %}">{ { blog_type.type_name }}</a </li {% empty %} <liNo classification</li> {% endfor %} </ul </div </div <div class="panel panel-default"> <div class="panel-heading" date archive </div <div class="panel-body"> <ul class="blog-types"> {% for blog_date in blog_dates %} <li<a href="{% url 'blogs_with_date' blog_date.year blog_date.month %}">{ { blog_date|date:"Year m month" }}</a></li {% endfor %} </ul </div </div </div ...
Organize code to reduce duplication
Modify blog/views.py:
from django.shortcuts import render_to_response, get_object_or_404 from django.core.paginator import Paginator from django.conf import settings from .models import Blog, BlogType def get_blog_list_common_data (request, blogs_all_list): paginator = Paginator(blogs_all_list, settings. BLOGS_NUM_PER_PAGE) page_num = request.GET.get('page', 1) # Get the page number parameter of the url. GET returns a dictionary, page_num defaults to 1 page_of_blogs = paginator. get_page(page_num) current_page_num = page_of_blogs.number # Get the current page number # Get the pages before and after page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + list(range (current_page_num, min(current_page_num + 2, paginator.num_pages) + 1)) # add ellipsis if page_range[0] - 1 > = 2: page_range.insert(0, '...') if paginator.num_pages - page_range[-1] >= 2: page_range.append('...') # Add the first and last page numbers if page_range[0] != 1 : page_range.insert(0, 1) if page_range[-1] != paginator.num_pages: page_range.append(paginator.num_pages) context = {} context['page_of_blogs'] = page_of_blogs # context['blogs_count'] = Blog.objects.all().count() context['blog_types'] = BlogType.objects.all() context['page_range'] = page_range context['blog_dates'] = Blog.objects.dates('created_time', 'month', order='DESC') # created_time descending order by month span> return context def blog_list (request): blogs_all_list = Blog.objects.all() context = get_blog_list_common_data(request, blogs_all_list) return render_to_response('blog/blog_list.html', context) def blog_detail (request, blog_pk): blog = get_object_or_404(Blog, pk=blog_pk) context = {} context['blog'] = blog context['previous_blog'] = Blog.objects.filter(created_time__gt=blog.created_time).last() context['next_blog'] = Blog.objects.filter(created_time__lt=blog.created_time).first() return render_to_response('blog/blog_detail.html', context) def blogs_with_type (request, blog_type_pk): blog_type = get_object_or_404(BlogType, pk=blog_type_pk) blogs_all_list = Blog.objects.filter(blog_type=blog_type) context = get_blog_list_common_data(request, blogs_all_list) context['blog_type'] = blog_type return render_to_response('blog/blogs_with_type.html', context) def blogs_with_date (request, year, month): blogs_all_list = Blog.objects.filter(created_time__year=year, created_time__month=month) context = get_blog_list_common_data(request, blogs_all_list) context['blogs_with_date'] = "%s year %s month" % (year, month) return render_to_response('blog/blogs_with_date.html', context)
g.objects.all()
context = get_blog_list_common_data(request, blogs_all_list)
return render_to_response(‘blog/blog_list.html’, context)
def blog_detail (request, blog_pk):
blog = get_object_or_404(Blog, pk=blog_pk)
context = {}
context[‘blog’] = blog
context[‘previous_blog’] = Blog.objects.filter(created_time__gt=blog.created_time).last()
context[‘next_blog’] = Blog.objects.filter(created_time__lt=blog.created_time).first()
return render_to_response(‘blog/blog_detail.html’, context)
def blogs_with_type (request, blog_type_pk):
blog_type = get_object_or_404(BlogType, pk=blog_type_pk)
blogs_all_list = Blog.objects.filter(blog_type=blog_type)
context = get_blog_list_common_data(request, blogs_all_list)
context[‘blog_type’] = blog_type
return render_to_response(‘blog/blogs_with_type.html’, context)
def blogs_with_date (request, year, month):
blogs_all_list = Blog.objects.filter(created_time__year=year, created_time__month=month)
context = get_blog_list_common_data(request, blogs_all_list)
context[‘blogs_with_date’] = “%s year %s month” % (year, month)
return render_to_response(‘blog/blogs_with_date.html’, context)