Django搭建个人博客平台5---首页对应视图函数相关逻辑

Posted 大聪明Smart

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django搭建个人博客平台5---首页对应视图函数相关逻辑相关的知识,希望对你有一定的参考价值。

Django搭建个人博客平台5—首页对应视图函数相关逻辑

视图函数

官方文档

可以参考官方文档,也可以看我前边写的博客。

介绍一下两种放方式CBV和FBV,我们采用的是CBV方式。

CBV和FBV

FBV(function base views) 就是在视图里使用函数处理请求。

CBV(class base views) 就是在视图里使用类处理请求。

Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:

  1. 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
  2. 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
# CBV
# views.py
from django.shortcuts import render, HttpResponse, redirect
from django.views import View
class LoginView(View):
    def dispatch(self, request, *args, **kwargs):
        print('请求来了')
        ret = super().dispatch(request, *args, **kwargs)
        print('请求处理完走了')
        return ret

    # GET 通过反射找的
    def get(self, request):
        print('get方法执行了')
        return render(request, 'login2.html')

    def post(self, request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(username, password)
        return HttpResponse('登录成功!')
# urls.py
from app01 import views

urlpatterns = [
    url(r'^login2/', views.LoginView.as_view()),
    
]

加装饰器

# FBV
# 装饰器
def wrapper(f):
    def inner(*args, **kwargs):
        print("添加额外的功能:执行被装饰函数之前的操作")
        ret = f(*args, **kwargs)
        print("添加额外的功能:执行被装饰函数之后的操作")
        return ret
    return inner
@wrapper
def home(request):
   
    return render(request, 'home.html')


# CBV
from django.shortcuts import render, HttpResponse, redirect
from django.views import View
from django.utils.decorators import method_decorator
# 装饰器
def wrapper(f):
    def inner(*args, **kwargs):
        print("添加额外的功能:执行被装饰函数之前的操作")
        ret = f(*args, **kwargs)
        print("添加额外的功能:执行被装饰函数之后的操作")
        return ret
    return inner
@method_decorator(wrapper, name='get')  # 方式3 给只当函数加装饰器
class LoginView(View):
    # @method_decorator(wrapper)  # 方式2 给所有的方法加
    def dispatch(self, request, *args, **kwargs):
        print('请求来了')
        ret = super().dispatch(request, *args, **kwargs)
        print('请求处理完走了')
        return ret

    # GET 通过反射找的
    # @method_decorator(wrapper)  # 方式1给单独的一个方法加
    def get(self, request):
        print('get方法执行了')
        return render(request, 'login2.html')

    def post(self, request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(username, password)
        return HttpResponse('登录成功!')

url配置

首先要配置相关的url才能找到对应的视图。

url无名分组和有名分组

无名分组

# urls.py
from app01 import views

urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^books/(\\d{4})/(\\d{1,2})/', views.books),# 匹配年月份
]
# views.py
def books(request, year, month): # 接收正则匹配到的数据
    # return render(request, 'books.html')
    print(year, month)
    return HttpResponse(year+month)

有名分组

from app01 import views

urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    # url(r'^books/(\\d{4})/(\\d{1,2})/', views.books),# 匹配年月份
    url(r'^books/(?P<year>\\d{4})/(?P<month>\\d{1,2})/', views.books),# 匹配年月份
    # {'yera':'2001', 'month':'12'}
]
# views.py
def books(request, year, month): # 接收正则匹配到的数据,名字一定要和url中的分组名一样,位置可以改变
    # return render(request, 'books.html')
    print(year, month)
    return HttpResponse(year+month)

urls.py

from django.contrib import admin
from django.urls import path, re_path, include

from blog import views


urlpatterns = [
    path('admin/', admin.site.urls, name='admin'),
    # 首页
    path('', views.Index.as_view(), name='index'),
    # 文章分类
    re_path(r'^articles/category/(?P<en_us_c>.*)/', views.Index.as_view(), name='category'),
    # 文章按标签分
    re_path(r'^articles/tag/(?P<en_us_c>.*)/(?P<en_us_tag>.*)/', views.Index.as_view(), name='tag'),
    # ....
    # 其他路由,后边用到再配
    # ....
    # 全站图标
    path('favicon.ico', favicon_view),
]
# 设置后台名称
admin.site.site_header = '大聪明博客后台'
admin.site.site_title = 'Django Blog 后台'

index视图类

实现逻辑

接受两个默认参数en_us_c=None, en_us_tag=None 对默认参数进行判断以区分是哪个url发起的请求,一个视图函数实现三个页面的渲染。

if tag_id:
    return render('标签页')
elif cid:
    return render('分类页')
else:
    return render('首页')

还有一点就是我门自己封装了一个分页组件,下一节会讲。现在可以先不考虑分页。

最后就是对所需要的数据使用ORM进行一个增删改查的操作即可,中间对数据的处理比如排序过滤等等。不会的参考我之前的博客。

后话

我的博客目前正常运行,这是我自己建立博客网站的记录和总结。如果你按照我的教程去做,一般是不会出现问题 ,但是,总会有bug发生。如果你遇到了问题,欢迎与我交流沟通。

最后,如果你觉得这篇文章对你有用的话,欢迎一键三连酌情打赏,谢谢!

最后附上代码

class Index(View):

    def get(self, request, en_us_c=None, en_us_tag=None):
        """首页展示"""
        print(en_us_c, en_us_tag)
        cid = en_us_c
        tag_id = en_us_tag
        if en_us_c:
            if en_us_c != 'category':
                c_obj = models.Category.objects.filter(en_us=en_us_c).first()
                cid = c_obj.id
        if en_us_tag:
            tag_obj = models.Tag.objects.filter(en_us=en_us_tag).first()
            tag_id = tag_obj.id


        print(cid, tag_id)
        # 文章对象
        article_obj = models.Article.objects.filter(is_display=False)
        # 评论对象
        comment_obj = models.Comment.objects.all()
        # 文章总数
        article_count = article_obj.count()
        # 评论总数
        comment_count = comment_obj.count()
        page_id = request.GET.get('page')  # 获取get请求中的page数据
        num = models.Article.objects.all().count()  # 总共记录数
        base_url = request.path  # 请求路径
        get_data = request.GET.copy()  # 直接调用这个类自己的copy方法或者deepcopy方法或者自己import copy 都可以实现内容允许修改
        # models.Article.objects.filter(is_recommend=1).update(add_time=time)  # <QuerySet [<Article: 太黑的诱惑>]>
        # all_articles = models.Article.objects.all().order_by('-add_time')  # <QuerySet [<Article: 333>]>
        top_articles = list(article_obj.filter(is_recommend=1).order_by('-add_time'))
        articles = list(article_obj.filter(is_recommend=False).order_by('-add_time'))
        all_articles = top_articles + articles
        # 以后直接在settings配置文件中修改即可
        page_count = settings.PAGE_COUNT  # 页数栏显示多少个数
        record = settings.RECORD  # 每页显示多少条记录
        html_obj = MyPagination(page_id=page_id, num=num, base_url=base_url, get_data=get_data, page_count=page_count,
                                record=record)
        # all_articles = articles | top_articles  # 合并两个queryset
        all_articles = all_articles[
                       (html_obj.page_id - 1) * html_obj.record:html_obj.page_id * html_obj.record]
        # P = models.Article.objects.get(id=8)
        # print(P.get_absolute_url())
        # 文章分类
        categories = models.Category.objects.all()
        # 文章专栏
        columns = models.Column.objects.all().order_by('-weights')

        # 最新文章
        new_articles = article_obj.order_by('-add_time')[:5]
        # 最热文章
        hot_articles = article_obj.order_by('-click_count')[:5]
        # 最新评论
        new_comments = comment_obj.order_by('-add_time')[:5]
        # 标签云
        tags = models.Tag.objects.all()
        # 登录的用户对象
        user_id = request.session.get('user_id')
        if user_id:
            cur_user_name = models.UserInfo.objects.get(id=user_id)
            qq_number = cur_user_name.email[:-7]
        else:
            cur_user_name = None
            qq_number = None

        qq_url = f'http://q.qlogo.cn/headimg_dl?dst_uin={qq_number}&spec=640&img_type=jpg'

        # 管理员用户对象
        admin_obj = models.UserInfo.objects.filter(is_admin=True).first()

        if tag_id:
            # tag_id对应类下的所有文章
            obj = models.Article.objects.filter(is_display=False).filter(tag__pk=tag_id)
            tags_num = obj.count() # 总共记录数
            tags_top_articles = list(obj.filter(is_recommend=1).order_by('-add_time'))
            tags_articles = list(obj.filter(is_recommend=False).order_by('-add_time'))
            tags_all_articles = tags_top_articles + tags_articles
            html_obj = MyPagination(page_id=page_id, num=tags_num, base_url=base_url, get_data=get_data,
                                    page_count=page_count, record=record)
            tags_all_articles = tags_all_articles[
                                (html_obj.page_id - 1) * html_obj.record:html_obj.page_id * html_obj.record]
            return render(request, 'tag.html',
                          {'tags_all_articles': tags_all_articles, 'page_html': html_obj.html_page(),
                           'categories':
                               categories, 'article_count': article_count, 'comment_count': comment_count,
                           'new_articles': new_articles, 'hot_articles':
                               hot_articles, 'new_comments': new_comments, 'tags': tags, 'cur_user_name': cur_user_name,
                           'qq_url': qq_url, 'admin_obj': admin_obj, 'columns': columns, })

        elif cid:
            # categoriy_id对应类下的所有文章
            categories_obj = models.Article.objects.filter(is_display=False).filter(category_id=cid)
            categories_num = categories_obj.count()  # 总共记录数
            categories_top_articles = list(categories_obj.filter(is_recommend=1).order_by('-add_time'))
            categories_articles = list(categories_obj.filter(is_recommend=False).order_by('-add_time'))
            categories_all_articles = categories_top_articles + categories_articles
            html_obj = MyPagination(page_id=page_id, num=categories_num, base_url=base_url, get_data=get_data,
                                    page_count=page_count, record=record)
            categories_all_articles = categories_all_articles[
                                      (html_obj.page_id - 1) * html_obj.record:html_obj.page_id * html_obj.record]
            return render(request, 'category.html',
                          {'categories_all_articles': categories_all_articles, 'page_html': html_obj.html_page(),
                           'categories':
                               categories, 'article_count': article_count, 'comment_count': comment_count,
                           'new_articles': new_articles, 'hot_articles':
                               hot_articles, 'new_comments': new_comments, 'tags': tags, 'cur_user_name': cur_user_name,
                           'qq_url': qq_url, 'admin_obj': admin_obj, 'columns': columns, })
        else:
            return render(request, 'index.html',
                          {'all_articles': all_articles, 'page_html': html_obj.html_page(), 'categories':
                              categories, 'article_count': article_count, 'comment_count': comment_count,
                           'new_articles': new_articles, 'hot_articles':
                               hot_articles, 'new_comments': new_comments, 'tags': tags, 'cur_user_name': cur_user_name,
                           'qq_url': qq_url, 'admin_obj': admin_obj, 'columns': columns, })

以上是关于Django搭建个人博客平台5---首页对应视图函数相关逻辑的主要内容,如果未能解决你的问题,请参考以下文章

Django搭建个人博客平台6---前端templates模板index页

Django搭建个人博客平台6---前端templates模板index页

实战项目之Django博客-5. 博客首页视图

Django测试平台开发开发博客

Django搭建个人博客平台2---创建一个Django项目和项目梳理

Django搭建个人博客平台2---创建一个Django项目和项目梳理