Django-开发一个列表页面

news2024/11/18 20:15:54

需求

  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.coloradmin.cn/o/1867256.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【STM32-存储器映射】

STM32-存储器映射 ■ STM32F1-4G地址空间分成8个块■ STM32F1-Block0■ STM32F1-Block1■ STM32F1-Block2■ STM32F1- ■ STM32F1-4G地址空间分成8个块 ■ STM32F1-Block0 有出厂 BootLoader 就可以使用串口下载程序。如Keil5图中IROM地址是0x8000000 开始 就是flash地址 ■ S…

安装vue开发者工具

浏览器控制台提示&#xff1a; 打开网址 GitHub - vuejs/devtools: ⚙️ Browser devtools extension for debugging Vue.js applications. 点击添加 上图地址&#xff1a;Installation | Vue Devtools 安装好了

线上民族传统服饰商城

摘 要 随着互联网的不断发展和普及&#xff0c;电子商务成为了人们生活中不可或缺的一部分。传统的线下购物方式逐渐被线上购物所取代&#xff0c;人们越来越习惯在互联网上购物。而民族传统服饰作为我国丰富多样的民族文化的重要组成部分&#xff0c;具有独特的艺术价值和商业…

不是KVM不支持精简置备的磁盘,而是VMM

正文共&#xff1a;999 字 11 图&#xff0c;预估阅读时间&#xff1a;1 分钟 书接上文&#xff08;不会吧&#xff01;KVM竟然不支持磁盘的精简置备&#xff01;&#xff1f;&#xff09;&#xff0c;我们已经掌握了通过“虚拟系统管理器VMM”创建虚拟机的基本方法&#xff0c…

vscode设置主题的颜色

点击主界面左下角的 展开的菜单中点击“themes” 点击“color themes” 选择颜色

windows USB 设备驱动开发-总章

通用串行总线 (USB) 提供可扩展的即插即用串行接口&#xff0c;确保外围设备的标准、低成本的连接。 USB 设备包括键盘、鼠标、游戏杆、打印机、扫描仪、存储设备、调制解调器、视频会议摄像头等。USB-IF 是一个特别兴趣组 (SIG)&#xff0c;负责维护官方 USB 规范、测试规范和…

浅谈Tomcat

文章目录 一、什么是Tomcat&#xff1f;二、Tomcat的下载安装三、使用tomcat访问资源 一、什么是Tomcat&#xff1f; Tomcat 就是一个 HTTP 服务器。 前面我们聊了HTTP服务器&#xff0c;像我们在网页输入URL&#xff0c;其实就是在给人家的HTTP服务器发送请求&#xff0c;既…

如何使用sr2t将你的安全扫描报告转换为表格格式

关于sr2t sr2t是一款针对安全扫描报告的格式转换工具&#xff0c;全称为“Scanning reports to tabular”&#xff0c;该工具可以获取扫描工具的输出文件&#xff0c;并将文件数据转换为表格格式&#xff0c;例如CSV、XLSX或文本表格等&#xff0c;能够为广大研究人员提供一个…

Renesas MCU使用SCI_I2C驱动HS3003

目录 概述 1 软硬件介绍 1.1 软件版本信息 1.2 认识HS3003 1.2.1 HS3003特性 1.2.2 HS3003寄存器 1.2.2.1 温湿度数据寄存器 1.2.2.2 参数寄存器 1.2.2.3 一个参数配置Demo 1.2.3 温湿度值转换 1.2.4 HS3003应用电路 1.2.4.1 PIN引脚定义 1.2.4.2 sensor 应用电路 …

从零入门激光SLAM(十三)——LeGo-LOAM源码超详细解析3

大家好呀&#xff0c;我是一个SLAM方向的在读博士&#xff0c;深知SLAM学习过程一路走来的坎坷&#xff0c;也十分感谢各位大佬的优质文章和源码。随着知识的越来越多&#xff0c;越来越细&#xff0c;我准备整理一个自己的激光SLAM学习笔记专栏&#xff0c;从0带大家快速上手激…

grpc学习golang版( 四、多服务示例)

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 文章目录 一、前言二、定义proto文件三、编写server服务端四、编写Client客户端五、测试六、示例代码 一、前言 多服务&#xff0c;即一个rpc提供多个服务给外界调用…

js+php 上传文件到服务器

https://andi.cn/page/621473.html

沙盒在数据防泄密领域意义

在信息化快速发展的今天&#xff0c;数据已成为企业最宝贵的资产之一。然而&#xff0c;数据泄密事件频发&#xff0c;给企业的安全和发展带来了巨大威胁。SDC沙盒防泄密系统&#xff0c;作为一种创新的数据防泄密解决方案&#xff0c;正逐渐在数据防泄密领域发挥着越来越重要的…

计算机网络期末复习(大题+小题)

计算机网络期末复习 一、计算机网络概述 Point 1 计算机网络就是以传输信息为基本目的&#xff0c;用通信线路和通信设备将多个计算机连接起来的计算机系统的集合。由自治的计算机互联起来的结合体。 Point 2 按网络的覆盖范围进行分类 &#xff08;1&#xff09;局域网*…

[leetcode]k-th-smallest-in-lexicographical-order 字典序的第K小数字

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int getSteps(int curr, long n) {int steps 0;long first curr;long last curr;while (first < n) {steps min(last, n) - first 1;first first * 10;last last * 10 9;}return steps;}int find…

深度学习11-20

1.神经元的个数对结果的影响&#xff1a; &#xff08;http://cs.stanford.edu/people/karpathy/convnetjs/demo/classify2d.html&#xff09; &#xff08;1&#xff09;神经元3个的时候 &#xff08;2&#xff09;神经元是10个的时候 神经元个数越多&#xff0c;可能会产生…

海南云亿商务咨询有限公司解锁抖音电商新纪元

在数字时代的浪潮中&#xff0c;电商行业如日中天&#xff0c;其中抖音电商更是异军突起&#xff0c;成为无数商家和创业者关注的焦点。而在这股汹涌的电商洪流中&#xff0c;海南云亿商务咨询有限公司凭借其专业的服务、深厚的行业背景和独特的创新理念&#xff0c;成为了抖音…

【Python机器学习】分享、离散化、线性模型与树

数据表示的最佳方法不仅取决于数据的语义&#xff0c;还取决于所使用的模型种类。线性模型与基于树的模型&#xff08;比如决策树、梯形提升树、随机森林&#xff09;是两种成员很多同时又非常常用的模型&#xff0c;他们在处理不同的特征表示时就具有非常不同的性质。 下面是…

数据结构与算法笔记:高级篇 - 概率统计:如何利用朴素贝叶斯算法过滤垃圾短信?

概述 上篇文章我们讲到&#xff0c;如何用位图、布隆过滤器&#xff0c;来过滤重复数据。本章&#xff0c;我们再讲一个跟过滤相关的问题&#xff0c;如果过滤垃圾短信&#xff1f; 垃圾短信和骚扰电话&#xff0c;我想每个人都收到过吧&#xff1f;买房、贷款、投资理财、开…

【JavaScript】流程控制和函数

目录 一、分支语句 1、if语句&#xff1a; 2、switch语句&#xff1a; 二、循环语句 1、while循环语句 2、for循环语句 三、函数声明 1、function 函数名(形参列表){ 函数体 } 2、var 函数名function(形参列表){函数体} 一、分支语句 1、if语句&#xff1a; if(表达式){ }else …