Django中class-based view的使用示例

Django中class-based view的使用示例

代码如下:
""" class-based view """
from django.db.models import Q
from django.shortcuts import get_object_or_404
from django.views.generic import ListView, DetailView

from config.models import SideBar
from .models import Post, Tag, Category


# 公共view
class CommonViewMixin:
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({
            'sidebars': SideBar.get_all(),
        })
        context.update(Category.get_navs())
        return context


# 处理首页的HTTP请求view
class IndexView(CommonViewMixin, ListView):
    queryset = Post.latest_posts()  # 获取数据
    paginate_by = 5  # 每页显示的记录数量
    context_object_name = 'post_list'  # 设置queryset的变量名称,用于在模板中调用
    template_name = 'blog/list.html'  # 渲染使用的模板文件


# category列表页view
class CategoryView(IndexView):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        category_id = self.kwargs.get('category_id')
        category = get_object_or_404(Category, pk=category_id)
        context.update({
            'category': category,
        })
        return context

    def get_queryset(self):
        """ 重写queryset,根据分类过滤 """
        queryset = super().get_queryset()  # 此处返回IndexView的queryset属性
        category_id = self.kwargs.get('category_id')
        return queryset.filter(category_id=category_id)  # 关键字参数:一对一外键category_id


# tag列表页view
class TagView(IndexView):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        tag_id = self.kwargs.get('tag_id')
        tag = get_object_or_404(Tag, pk=tag_id)
        context.update({
            'tag': tag,
        })
        return context

    def get_queryset(self):
        """ 重写queryset,根据标签过滤"""
        queryset = super().get_queryset()  # 此处返回IndexView的queryset属性
        tag_id = self.kwargs.get('tag_id')
        return queryset.filter(tag__id=tag_id)  # 关键字参数:多对多外键要tag__id


# 文章详情页view
class PostDetailView(CommonViewMixin, DetailView):
    queryset = Post.latest_posts()
    template_name = 'blog/detail.html'
    context_object_name = 'post'  # 设置传递到模板文件的变量名称
    pk_url_kwarg = 'post_id'  # 在DetailView中,会根据这个参数来过滤数据,如:post = queryset.filter(pk=post_id)


# 搜索列表页view
class SearchView(IndexView):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context.update({
            'keyword': self.request.GET.get('keyword', '')
        })
        return context

    def get_queryset(self):
        queryset = super().get_queryset()
        keyword = self.request.GET.get('keyword', '')
        if not keyword:
            return queryset
        return queryset.filter(Q(title__icontains=keyword) | Q(desc__icontains=keyword))


# 根据作者过滤的列表页view
class AuthorView(IndexView):
    def get_queryset(self):
        queryset = super().get_queryset()
        author_id = self.kwargs.get('owner_id')
        return queryset.filter(owner_id=author_id)
代码分析:

代码中的注释已经很好地解释了上面的代码。
1、class CommonViewMixin:
在这个公共类view,我们通过重写get_context_data函数来获取一些公用的数据,这些数据在各种页面中都需要展示,如:导航栏、侧边栏的数据

2、class IndexView(CommonViewMixin, ListView):
这个类继承了CommonViewMixin, ListView这两个类,实现了首页列表页的视图函数。
通过设置queryset属性来获取数据库中的文章数据:

queryset = Post.latest_posts()  # 获取数据

其他的属性说明在代码中有注释。
3、对于CategoryView(IndexView)、TagView(IndexView)、SearchView(IndexView)、AuthorView(IndexView):
这几个类view都继承了类IndexView(CommonViewMixin, ListView)
(1)通过重写get_context_data()函数来添加额外要获取的数据。
(2)通过重写get_queryset(self)函数来对IndexView(CommonViewMixin, ListView)中获取到queryset数据进行过滤。原因如下:
在CategoryView(IndexView)、TagView(IndexView)、SearchView(IndexView)、AuthorView(IndexView)这几个类get_queryset(self)函数中调用了父类的get_queryset(self)函数:

queryset = super().get_queryset()

因为在IndexView(CommonViewMixin, ListView)中设置了queryset属性:

queryset = Post.latest_posts()  # 获取数据

所以CategoryView(IndexView)、TagView(IndexView)、SearchView(IndexView)、AuthorView(IndexView)的这行代码:

queryset = super().get_queryset()

返回的即是父类IndexView(CommonViewMixin, ListView)的queryset属性。
接着,就可以对queryset 数据进行过滤了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值