Django-开发一个列表页面

需求

  1. 基于ListView,创建一个列表视图,用于展示"BookInfo"表的信息
  2. 要求提供分页
  3. 提供对书名,作者,描述的查询功能

示例展示:
在这里插入图片描述

1. 数据模型

models.py

class BookInfo(models.Model):
    title=models.CharField(verbose_name="书名",max_length=100)
    author=models.CharField(verbose_name="作者",max_length=100)
    desc=models.TextField(verbose_name="介绍")
    create_at=models.DateTimeField(verbose_name="创建时间",auto_now=True)
    update_at=models.DateTimeField(verbose_name="更新时间",auto_now_add=True)

2. 视图

views.py

from functools import reduce
from typing import Any
from django.shortcuts import render,redirect  
from django.db.models import Q
from django.views.generic import ListView
from django.views.generic.detail import DetailView
from .models import *
from .forms import *

class BookListView(ListView):
    model=BookInfo
    template_name = "demo1/book_list.html"
    paginate_by = 10
    def get_queryset(self):
        title = self.request.GET.get('title')
        author = self.request.GET.get('author')
        content = self.request.GET.get('content')
        # 如果有任意参数不为空,则构建Q对象进行查询
        queries = [Q(titile__icontains=title) if title else Q(),
                   Q(author__icontains=author) if author else Q(),
                   Q(desc__icontains=content) if content else Q()]
        # 使用Q对象的&操作符组合查询条件
        queryset = BookInfo.objects.filter(reduce(lambda x, y: x & y, queries)) if queries else BookInfo.objects.all()

        return queryset


    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # 保留查询参数到分页链接
        query_params = self.request.GET.copy()
        if 'page' in query_params:
            del query_params['page']  # 移除现有的页码参数以避免冲突

        paginator = context['paginator']
        page_numbers_range = 5  # 您可以根据需要调整显示的页码范围大小
        max_index = len(paginator.page_range)

        page = self.request.GET.get('page')
        current_page = int(page) if page else 1

        start_index = int((current_page - 1) / page_numbers_range) * page_numbers_range
        end_index = start_index + page_numbers_range
        if end_index >= max_index:
            end_index = max_index

        page_range = paginator.page_range[start_index:end_index]
        context['page_range'] = page_range
        context['query_params'] = query_params.urlencode()  # 将查询参数编码为URL字符串

        return context

    def get(self, request, *args, **kwargs):
        # 如果是重定向回来的,需要处理paginate_by参数
        if 'paginate_by' in request.GET:
            try:
                paginate_by = int(request.GET['paginate_by'])
                if paginate_by > 0:  # 防止不合法的值
                    self.paginate_by = paginate_by
            except ValueError:
                pass  # 如果转换失败,忽略错误,使用默认设置

        return super().get(request, *args, **kwargs)

class BookDetailView(DetailView):
    model=BookInfo
    template_name = "demo1/book_detail.html"
    context_object_name = "book"

注册路由(urls.py)

from django.urls import path
from .views import *

urlpatterns = [
   path("book",BookListView.as_view(),name="book-list"),
   path("book/detail/<int:pk>/",BookDetailView.as_view(),name="book-detail"),
]

3. 页面代码

列表页:

{% extends 'layout.html' %}

{% block main %}
    <div class="panel panel-default">
        <div class="container">
            <form method="GET">
                检索:
                <input type="text" name="title" placeholder="书名" value="{{ request.GET.title }}">
                <input type="text" name="author" placeholder="作者" value="{{ request.GET.author }}">
                <input type="text" name="content" placeholder="内容关键字" value="{{ request.GET.content }}">
                <button type="submit">搜索</button>&nbsp; <a href="{% url 'book-list' %}" class="btn-sm btn-danger">清空查询条件</a>
            </form>
        </div>
        <hr>
        <div class="panel-body">
            <table class="table table-striped">
                <thead>
                <tr>
                    <th>ID</th>
                    <th>书名</th>
                    <th>作者</th>
                    <th>说明</th>
                    <th>创建时间</th>
                    <th>更新时间</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>

                {% for book in object_list %}
                    <tr>
                        <td>{{ book.id }}</td>
                        <td>{{ book.titile }}</td>
                        <td>{{ book.author }}</td>
                        <td>{{ book.desc }}</td>
                        <td>{{ book.create_at }}</td>
                        <td>{{ book.update_at }}</td>
                        <td><a href="{% url 'book-detail' book.id %}">查看详情</a></td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>

            {% if is_paginated %}
                <div class="pagination">
                    <p>第 {{ page_obj.number }} 页 / 共 {{ page_obj.paginator.num_pages }} 页</p>
                    <!-- 首页 -->
                    {% if page_obj.has_previous %}
                        <a href="?{{ query_params }}&page=1">首页</a>
                    {% endif %}

                    <!-- 上一页 -->
                    {% if page_obj.has_previous %}
                        <a href="?{{ query_params }}&page={{ page_obj.previous_page_number }}">上一页</a>
                    {% endif %}



                    <!-- 中间页码,显示首末3页及当前页附近的页码,其余用省略号表示 -->
                    {% for num in page_obj.paginator.page_range %}
                        {% if num == page_obj.number %}
                            <span>{{ num }}</span> <!-- 当前页不做成链接 -->
                        {% elif num >= page_obj.number|add:-2 and num <= page_obj.number|add:2 %}
                            <a href="?{{ query_params }}&page={{ num }}">{{ num }}</a>
                        {% elif num in page_obj.paginator.page_range|slice:":3" or num in page_obj.paginator.page_range|slice:"-3:" %}
                            <a href="?{{ query_params }}&page={{ num }}">{{ num }}</a> <!-- 确保首末3页始终显示 -->
                        {% elif num == page_obj.number|add:-3 or num == page_obj.number|add:3 %}
                            <span>...</span>
                        {% endif %}
                    {% endfor %}
                    <!-- 下一页 -->
                    {% if page_obj.has_next %}
                        <a href="?{{ query_params }}&page={{ page_obj.next_page_number }}">下一页</a>
                    {% endif %}

                    <!-- 尾页 -->
                    {% if page_obj.has_next %}
                        <a href="?{{ query_params }}&page={{ page_obj.paginator.num_pages }}">尾页</a>
                    {% endif %}
                    <!-- 当前页及总页数信息 -->

                    <!-- 跳转到指定页的表单 -->
                    <label for="jumpToPage">跳转到页数:</label>
                    <input type="number" id="jumpToPage" min="1">
                    <button onclick="jumpToPage()">跳转</button>
                </div>
                </div>
            {% endif %}
    </div>

    <script>
        function jumpToPage() {
            var jumpTo = document.getElementById('jumpToPage').value;
            var currentQueryParams = new URLSearchParams(window.location.search);
            if (jumpTo.trim() !== '') { // 确保输入有效
                // 保留现有查询参数,并添加或更新'page'参数
                currentQueryParams.set('page', jumpTo);
                window.location.href = window.location.pathname + '?' + currentQueryParams.toString();
            } else {
                alert('请输入有效的页数');
            }
        }
    </script>
{% endblock %}

详情页(略)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/759023.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vscode中快捷生成自定义vue3模板

需求描述 新建 vue 文件后&#xff0c;需要先写出 vue3 的基础架构代码&#xff0c;手动输入效率低下&#xff01; 期待&#xff1a;输入 v3 按 Tab 即刻生成自定义的vue3模板&#xff08;如下图&#xff09; 实现流程 vscode 的设置中&#xff0c;选择 用户代码片段 输入 vue…

基于STM32的温湿度检测TFT屏幕proteus恒温控制仿真系统

一、引言 本文介绍了一个基于STM32的恒温控制箱检测系统&#xff0c;该系统通过DHT11温湿度传感器采集环境中的温湿度数据&#xff0c;并利用TFT LCD屏幕进行实时显示。通过按键切换页面显示&#xff0c;通过按键切换实现恒温控制箱的恒温控制。为了验证系统的可靠性和稳定性&…

密室逃脱——收集版

一、原版修改 1、导入资源 Unity Learn | 3D Beginner: Complete Project | URP 2、设置Scene 删除SampleScene&#xff0c;打开UnityTechnologies-3DBeginnerComplete下的MainScene 3、降低音量 (1) 打开Hierarchy面板上的Audio降低音量 (2) 打开Prefabs文件夹&#xf…

使用 PyQt5 创建一个数字时钟

使用 PyQt5 创建一个数字时钟 效果代码解析定义时钟类初始化界面显示时间 完整代码 在这篇博客中&#xff0c;我们将使用 PyQt5 创建一个简单的数字时钟。 效果 代码解析 定义时钟类 class ClockWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTit…

Swift宏的实现

上篇介绍了Swift宏的定义与生声明&#xff0c;本篇主要看看是Swift宏的具体实现。结合Swift中Codable协议&#xff0c;封装一个工具让类或者结构体自动实现Codable协议&#xff0c;并且添加一些协议中没有的功能。 关于Codable协议 Codable很好&#xff0c;但是有一些缺陷&…

Redis基础教程(三):redis命令

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

仓库管理系统11--物资设置

1、添加用户控件 <UserControl x:Class"West.StoreMgr.View.GoodsTypeView"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc"http://schemas.openxm…

sqlserver开启CDC

1、背景 由于需要学习flink cdc&#xff0c;并且数据选择sqlserver&#xff0c;所以这里记录sqlserver的cdc开启操作步骤。 2、基础前提 官方介绍地址&#xff1a;https://learn.microsoft.com/zh-cn/sql/relational-databases/track-changes/enable-and-disable-change-dat…

Ubuntu22.04 源码安装 PCL13+VTK-9.3+Qt6,踩坑记录

Ubuntu 22.04LTS;cmake-3.25.0;VTK-9.3;PCL-1.13;Qt6.6 PCL可以通过 apt 命令直接安装(sudo apt install libpcl-dev),apt 命令安装的 VTK 是简略版,没有对 Qt 支持的包,所以笔者使用源码安装 PCL 和 VTK。 1. 安装 VTK 1) 安装 ccmake 和 VTK 依赖项: sudo apt-g…

DataWhale-吃瓜教程学习笔记 (五)

学习视频&#xff1a;第4章-决策树_哔哩哔哩_bilibili 西瓜书对应章节&#xff1a; 第四章 4.1&#xff1b;4.2 文章目录 决策树算法原理- 逻辑角度- 几何角度 ID3 决策树- 自信息- 信息熵 &#xff08;自信息的期望&#xff09;- 条件熵 &#xff08; Y 的信息熵关于概率分布 …

从万里长城防御体系看软件安全体系建设@安全历史03

长城&#xff0c;是中华民族的一张重要名片&#xff0c;是中华民族坚韧不屈、自强不息的精神象征&#xff0c;被联合国教科文组织列入世界文化遗产名录。那么在古代&#xff0c;长城是如何以其复杂的防御体系&#xff0c;一次次抵御外族入侵&#xff0c;而这些防御体系又能给软…

HarmonyOS Next开发学习手册——创建轮播 (Swiper)

Swiper 组件提供滑动轮播显示的能力。Swiper本身是一个容器组件&#xff0c;当设置了多个子组件后&#xff0c;可以对这些子组件进行轮播显示。通常&#xff0c;在一些应用首页显示推荐的内容时&#xff0c;需要用到轮播显示的能力。 针对复杂页面场景&#xff0c;可以使用 Sw…

C++ sizeof的各种

C sizeof的各种 1. 含有虚函数的类对象的空间大小2. 虚拟继承的类对象的空间大小3. 普通变量所占空间大小4. 复合数据类型&#xff08;结构体和类&#xff09;5. 数组6. 类型别名7. 动态分配内存8. 指针9. 静态变量10. 联合体11. 结构体使用#program pack 1. 含有虚函数的类对象…

firewalld防火墙转发流量到其他端口forward port rules

假设云主机eth0: 47.93.27.106 tun0: inet 10.8.0.1 netmask 255.255.255.0 Show rules for a specific zone (public) sudo firewall-cmd --zonepublic --list-all Add the tun0 interface to the public zone: sudo firewall-cmd --zonepublic --add-interfacetun0 --…

关于图片大小问题造成的QPixmap或QImage读取图片失败的解决办法

今天碰到一个奇怪又离谱的问题 : 图片加载失败。明明路径是正确的&#xff0c;图片也实实在在存在。。。 经过比对&#xff0c;发现如下问题&#xff1a; 我就齐了怪了 这大小怎么差这么多&#xff1f;会不会是这里除了问题。秉持着怀疑的态度&#xff0c;我试着用GIMP重新导出…

机械设计简单介绍

机械设计简单介绍 1 介绍1.1 概述1.2 机械机构设计基本步骤1.3 关键1.3.1 静力学1.3.2 动力学1.3.3 运动学1.3.4 刚度学 1.4 示例【机械臂】 2 资料2.1 知识体系2.2 博客类汇总2.3 免费CAD模型获取2.4 3D打印2.5 SolidWorks 3 具备能力3.1 熟练翻阅 机械设计手册3.2 知道 N 家常…

【01-02】Mybatis的配置文件与基于XML的使用

1、引入日志 在这里我们引入SLF4J的日志门面&#xff0c;使用logback的具体日志实现&#xff1b;引入相关依赖&#xff1a; <!--日志的依赖--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version&g…

Part 8.3.3 最近公共祖先

两个点的最近公共祖先&#xff0c;即两个点的所有公共祖先中&#xff0c;离根节点最远的一个节点。 【模板】最近公共祖先&#xff08;LCA&#xff09; 题目描述 如题&#xff0c;给定一棵有根多叉树&#xff0c;请求出指定两个点直接最近的公共祖先。 输入格式 第一行包含…

VMware虚拟机安装CentOS7.9 Oracle 11.2.0.4 RAC+单节点RAC ADG

目录 一、参考资料 二、RAC环境配置清单 1.主机环境 2.共享存储 3.IP地址 4.虚拟机 三、系统参数配置 1. 配置网卡 1.1 配置NAT网卡 1.2 配置HostOnly网卡 2. 修改主机名 3. 配置/etc/hosts 4. 关闭防火墙 5. 关闭Selinux 6. 配置内核参数 7. 配置grid、oracle…

vue3:星星评分组件

一、效果 二、代码 子组件stars.vue&#xff1a; <template><div class"stars"><div class"star" v-for"star in stars" :key"star" click"setScore(star)"><svgt"1719659437525"class&qu…