1.分页器

分页器相关知识点,请查看以下链接

https://www.cnblogs.com/gbq-dog/p/10724859.html

2.代码归类

归类前代码

header_list = []  # 定制一个空别表
for field_or_func in self.get_new_list_display():
# 如果是多对多的
if callable(field_or_func):
val = field_or_func(self, header=True)
header_list.append(val)
# header_list.append(field_or_func.__name__)
# 如果是普通属性
else: if field_or_func == "__str__":
val = self.model._meta.model_name.upper()
else:
field_obj = self.model._meta.get_field(field_or_func)
val = field_obj.verbose_name # 自定义属性名 header_list.append(val) # 构建展示数据
new_data = []
for obj in queryset:
temp = []
for field_or_func in self.get_new_list_display():
if callable(field_or_func):
val = field_or_func(self, obj) # 获取函数返回值,传入obj进行从操作数据 elif not field_or_func == "__str__":
from django.db.models.fields.related import ManyToManyField
field_obj = self.model._meta.get_field(field_or_func) # 获取模型对象
# 判断是否为多对多属性
if type(field_obj) == ManyToManyField:
raise Exception("list_display不能是多对多字段!")
# 判断是否有选择属性
if field_obj.choices:
val = getattr(obj, "get_%s_display" % field_or_func)()
# 调用这个方法,反射方法,调用方法获取对应的内容
else:
val = getattr(obj, field_or_func)
if field_or_func in self.list_display_links:
val = mark_safe("<a href='%s'>%s</a>" % (self.get_change_url(obj), val)) else:
val = getattr(obj, field_or_func)() temp.append(val)
# print(">>>>>>>>>>>>",temp)
new_data.append(temp)

归类前代码

2.1 原本内容整理

2.1.1 创建展示类

在原内容地方通过实例对象调用内容

2.1.2 函数展示

2.1.3 调用说明

  • requset ,当前操作请求  对应requset
  • self ,当前操作自定义配置类, 对应config_obj
  • quseryset   当前操作数据对应 queryse

2.2 分页包调用以及配置

2.2.1知识点

ruquset.GET.get("筛选内容",默认值=None) 即如果不写默认值则为空,这里写为1 即,没获取到时候为1

2.2.2 设置接口

2.2.3 获取数据

获取分好页的数据(通过切片[开始:结束])

2.2.4 抬头部分

2.2.5 展示数据

2.2.6 前端的修改

前端效果:

归类后完整代码

from django.urls import path, re_path

from app01.models import *
from django.shortcuts import HttpResponse, render, redirect from django.utils.safestring import mark_safe
from django.urls import reverse class ShowList(object): #
def __init__(self, request, config_obj, queryset):
self.request = request # 接收请求
self.config_obj = config_obj #接收自定义配置类
self.queryset = queryset #接收数据
self.pager_queryset = self.get_pager_queryset() # 实例分页对象获取内容 def get_pager_queryset(self):
from stark.utils.page import Pagination # 导入自己写的分页包
current_page = self.request.GET.get("page", 1) # 当前操作页
self.pagination = Pagination(self.request, current_page, self.queryset,
per_page_num=self.config_obj.per_page_num or 5)
queryset = self.queryset[self.pagination.start:self.pagination.end]
return queryset def get_header(self):
header_list = [] # 定制一个空别表
for field_or_func in self.config_obj.get_new_list_display(): # 替换成config_obj 代用,self 代表原自定义配置类
# 如果是多对多的
if callable(field_or_func):
val = field_or_func(self, header=True)
header_list.append(val)
# header_list.append(field_or_func.__name__)
# 如果是普通属性
else: if field_or_func == "__str__":
val = self.config_obj.model._meta.model_name.upper()
else:
field_obj = self.config_obj.model._meta.get_field(field_or_func)
val = field_obj.verbose_name # 自定义属性名 header_list.append(val)
return header_list #f返回前端的内容
def get_body(self): # 构建展示数据
new_data = []
for obj in self.pager_queryset:
temp = []
for field_or_func in self.config_obj.get_new_list_display():
if callable(field_or_func):
val = field_or_func(self.config_obj, obj) # 获取函数返回值,传入obj进行从操作数据
# self 统一换成self.config_obj
elif not field_or_func == "__str__":
from django.db.models.fields.related import ManyToManyField
field_obj = self.config_obj.model._meta.get_field(field_or_func) # 获取模型对象
# 判断是否为多对多属性
if type(field_obj) == ManyToManyField:
raise Exception("list_display不能是多对多字段!")
# 判断是否有选择属性
if field_obj.choices:
val = getattr(obj, "get_%s_display" % field_or_func)()
# 调用这个方法,反射方法,调用方法获取对应的内容
else:
val = getattr(obj, field_or_func)
if field_or_func in self.config_obj.list_display_links:
val = mark_safe("<a href='%s'>%s</a>" % (self.config_obj.get_change_url(obj), val)) else:
val = getattr(obj, field_or_func)() temp.append(val)
# print(">>>>>>>>>>>>",temp)
new_data.append(temp) return new_data #返回前端数据部分
class ModelStark(object):
'''
默认配置类
'''
list_display = ("__str__",)
list_display_links = [] # 设置默认为空
model_form_class = None # 设置默认为无
per_page_num=None #设置接口
search_fields = [] #创建search_fidels接口
search_val = None # 默认让search_val的值为none
def __init__(self, model):
self.model = model
self.model_name = self.model._meta.model_name
self.app_label = self.model._meta.app_label # 反向解析当前访问表的增删改查URL def get_list_url(self):
# 反向解析当前表的删除的URL
list_url = reverse("%s_%s_list" % (self.app_label, self.model_name))
return list_url def get_add_url(self, obj=None):
# 反向解析当前表的删除的URL
add_url = reverse("%s_%s_add" % (self.app_label, self.model_name))
return add_url def get_delete_url(self, obj):
# 反向解析当前表的删除的URL
delete_url = reverse("%s_%s_delete" % (self.app_label, self.model_name), args=(obj.pk,))
return delete_url def get_change_url(self, obj):
# 反向解析当前表的change的URL
change_url = reverse("%s_%s_change" % (self.app_label, self.model_name), args=(obj.pk,))
return change_url def get_new_list_display(self):
temp = []
temp.extend(self.list_display) # 继承原来的列表内容
temp.append(ModelStark.show_editbtn) # 注意传过来的是属性
temp.append(ModelStark.show_delbtn) # 注意传过来的是属性
temp.insert(0, ModelStark.show_checkbox)
# temp.insert(1,self.show_checkbox())
# 同上不加括号,把方法名加入到列表方便掉用
return temp def show_checkbox(self, obj=None, header=False):
# 展示选择列
if header:
return mark_safe("<input type='checkbox'>")
return mark_safe("<input type='checkbox'>") def show_delbtn(self, obj=None, header=False):
if header:
return "删除" return mark_safe("<a href='%s'>删除</a>" % self.get_delete_url(obj)) def show_editbtn(self, obj=None, header=False):
if header:
return "编辑"
return mark_safe("<a href='%s'>编辑</a>" % self.get_change_url(obj)) def get_search_condition(self, request):
val = request.GET.get("q") # 获取name q的内容 from django.db.models import Q # 导入Q 包 .进行或操作
q = Q() # 实例一个Q 对象
if val:# 如果进行了查询操作
self.search_val = val
q.connector = "or" # 更改q为或操作
for field in self.search_fields: # ["title","price"] # 从接口中拿字段
print(field)
# queryset=queryset.filter(Q(title__contains=val)|Q(price__contains=val))
q.children.append((field + "__contains", val))
# 利用小q进行模糊查询,和拼接
# "__contains 模糊查询" 即 title__contains=val 查询
else:
self.search_val = None return q def list_view(self, request):
# print(self) # 当前访问模型表对应的配置类对象
# print(self.model) # 当前访问模型表
queryset = self.model.objects.all()
print("+>>>>>>>", queryset)
# 构建表头
queryset=queryset.filter(self.get_search_condition(request))
show_list = ShowList(request, self, queryset)
# 当前请求 ,当前操作的自定制配置类,当前所有数据
table_name = self.model._meta.verbose_name
add_url = self.get_add_url()
# print("<<<<<<<<<<<",new_data)
return render(request, "stark/list_view.html", locals()) # data = self.model.objects.all()
# print(data)
# print("-------",self.list_display)
# data_list=[]
# dict1={}
# for obj in data:
# lis =[]
# for msg in self.list_display:
# lis.append(getattr(obj,msg))
# data_list.append(lis)
# print("jjjjjjjjj",data_list)
# return render(request, 'stark/list_view.html', {
# "data_list":data_list,
# "list_display":self.list_display
# }) def get_model_form(self): # 创建获取model_form 内容函数
from django.forms import ModelForm # 导入包
class BaseModelForm(ModelForm): # 创建modelform类,继承modelform
class Meta: # 创建可调用内容
model = self.model # 导入当前操作模型对象
fields = "__all__" # 获取全部 return self.model_form_class or BaseModelForm # 如果有内容就传入内容,没有就走默认的Base的
# 有的时候需要重新写class BasemodelForm类并继承他 def add_view(self, request): # 视图函数add_view
BaseModelForm = self.get_model_form() # 通过get_model_form运行获取类
if request.method == "GET":
form_obj = BaseModelForm() # 实例化对象获取内容
return render(request, "stark/add_view.html", locals()) # 传到前端内容(属性)
else:
form_obj = BaseModelForm(request.POST) # 向渲染的模型类中加入数据
if form_obj.is_valid(): # 判断接收数据是否可用
form_obj.save() # 将数据保存到数据库
return redirect(self.get_list_url()) # 跳转
else:
return render(request, "stark/add_view.html", locals()) def change_view(self, request, id): # 创建change_view路由 ,传入request,id,通过反向解析获取id
BaseModelForm = self.get_model_form() # 通过方法获取modelform类
edit_obj = self.model.objects.filter(pk=id).first() # 通过id获取当前操作对象
if request.method == "GET":
form_obj = BaseModelForm(instance=edit_obj) # 通过instance参数,进行控制为传入对象可以到前端进行渲染
return render(request, "stark/change_view.html", locals())
else:
form_obj = BaseModelForm(request.POST, instance=edit_obj) # 接收前端内容,instance对象,是内容进行覆盖
if form_obj.is_valid():
form_obj.save() # 数据保存
return redirect(self.get_list_url())
else:
return render(request, "stark/change_view.html", locals()) def delete_view(self, request, id): # 接收反向解析传过来的id
if request.method == "POST":
self.model.objects.filter(pk=id).delete() # 接收id 删除主键
return redirect(self.get_list_url()) # 跳转
list_url = self.get_list_url() # 把展示界面传过去.方便用户取消 return render(request, "stark/delete_view.html", locals()) # 新建删除html @property
def get_urls(self):
temp = [
path("", self.list_view, name="%s_%s_list" % (self.app_label, self.model_name)),
path("add/", self.add_view, name="%s_%s_add" % (self.app_label, self.model_name)),
re_path("(\d+)/change/", self.change_view, name="%s_%s_change" % (self.app_label, self.model_name)),
re_path("(\d+)/delete/", self.delete_view, name="%s_%s_delete" % (self.app_label, self.model_name)),
] return (temp, None, None) class StarkSite:
'''
stark全局类
''' def __init__(self):
self._registry = {} def register(self, model, admin_class=None, **options):
admin_class = admin_class or ModelStark
self._registry[model] = admin_class(model) def get_urls(self):
# 动态为注册的模型类创建增删改查URL
temp = []
# {Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)}
for model, config_obj in self._registry.items():
# print("---->", model, config_obj)
model_name = model._meta.model_name
app_label = model._meta.app_label
temp.append(
path("%s/%s/" % (app_label, model_name), config_obj.get_urls)
) '''
path("stark/app01/book",self.list_view)
path("stark/app01/book/add",self.add_view)
path("stark/app01/publish",self.list_view)
path("stark/app01/publish/add",self.add_view) ''' return temp @property
def urls(self):
return self.get_urls(), None, None site = StarkSite()

归类后完整代码

3.搜索框

知识点:django中Q查询的使用,实例化Q以后可以进行更改内容且通过字符串进行修改

3.1 接口内容

注册接口内容

3.2 前端代码内容

设置name=q进行form表单数据进行操作,通过if进行判断如果有配置search_fidleds接口则显示出搜索框,否则则不显示搜索框

3.3 sites数据

__contains进行数据模糊查询

3.4 数据通过search进行数据过滤

3.5 展示如下

通过’啊’进行搜索

a

Django-CRM项目学习(四)-stark的分页器与搜索框的更多相关文章

  1. Spring Boot 项目学习 (四) Spring Boot整合Swagger2自动生成API文档

    0 引言 在做服务端开发的时候,难免会涉及到API 接口文档的编写,可以经历过手写API 文档的过程,就会发现,一个自动生成API文档可以提高多少的效率. 以下列举几个手写API 文档的痛点: 文档需 ...

  2. django——CRM项目

    1.引言 CRM,客户关系管理系统(Customer Relationship Management).企业用CRM技术来管理与客户之间的关系,以求提升企业成功的管理方式,其目的是协助企业管理销售循环 ...

  3. Django - CRM项目(3)

    一.CRM项目的业务逻辑与表结构梳理 1.分析业务逻辑 (1) 引流(sem) (2) 网络咨询师(客服):添加客户信息和查看客户,分配销售 (3) 销售:查看私户 添加跟进记录 失败:加入公户 成功 ...

  4. Django - CRM项目(2)Q查询(模糊查询)

    一.CRM项目(2) 利用Q查询中的q对象完成条件筛选功能. 批量删除.公户转私户功能. 新增一张跟进记录表ConsultRecord,迁移数据库并添加测试数据,实现跟进记录列表页面. 客户列表新增跟 ...

  5. WPF项目学习.四

    信息收录项目 版权声明:本文为博主初学经验,未经博主允许不得转载. 一.前言 记录在学习与制作WPF过程中遇到的解决方案.  需求文案.设计思路.简要数据库结构.简要流程图和明细代码,动图细化每步操作 ...

  6. Django ---- blog项目学习所得

    一.登录功能 1.采用ajax 提交form表单的方式 2.后台生成随机验证码,登录时提交验证码 3.用PLI库生成随机验证码,置于session中,登录时与前台提交的code进行upeer()的验证 ...

  7. Spring Boot 项目学习 (三) Spring Boot + Redis 搭建

    0 引言 本文主要介绍 Spring Boot 中 Redis 的配置和基本使用. 1 配置 Redis 1. 修改pom.xml,添加Redis依赖 <!-- Spring Boot Redi ...

  8. Spring Boot 项目学习 (一) 项目搭建

    0 引言 本文主要记录借用Idea 开发环境下,搭建 Spring Boot 项目框架的过程. 1 系列文档目录 Spring Boot 项目学习 (一) 项目搭建 Spring Boot 项目学习 ...

  9. Spring Boot 项目学习 (二) MySql + MyBatis 注解 + 分页控件 配置

    0 引言 本文主要在Spring Boot 基础项目的基础上,添加 Mysql .MyBatis(注解方式)与 分页控件 的配置,用于协助完成数据库操作. 1 创建数据表 这个过程就暂时省略了. 2 ...

随机推荐

  1. RxJS 实现摩斯密码(Morse) 【内附脑图】

    参加 2018 ngChina 开发者大会,特别喜欢 Michael Hladky 奥地利帅哥的 RxJS 分享,现在拿出来好好学习工作坊的内容(工作坊Demo地址),结合这个示例,做了一个改进版本, ...

  2. HotSpot虚拟机对象相关内容

    一.对象的创建 1.类加载检查 普通对象的创建过程:虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载.解析和初始化 ...

  3. Nginx的负载均衡

    什么是负载均衡 负载均衡主要通过专门的硬件设备或者通过软件算法实现.通过硬件设备实现的负载均衡效果好.效率高.性能稳定,但是成本比较高.通过软件实现的负载均衡主要依赖于均衡算法的选择和程序的健壮性.均 ...

  4. 【Java入门提高篇】Day25 史上最详细的HashMap红黑树解析

    当当当当当当当,好久不见,最近又是换工作,又是换房子,忙的不可开交,断更了一小段时间,最重要的一篇迟迟出不来,每次都犹抱琵琶半遮面,想要把它用通俗易懂的方式进行说明,确实有一定的难度,可愁煞我也,但自 ...

  5. Ansible 入门指南 - 安装及 Ad-Hoc 命令使用

    安装及配置 ansible Ansilbe 管理员节点和远程主机节点通过 SSH 协议进行通信.所以 Ansible 配置的时候只需要保证从 Ansible 管理节点通过 SSH 能够连接到被管理的远 ...

  6. Smobiler 4.4 更新预告 Part 1(Smobiler能让你在Visual Studio上开发APP)

    在4.4版本中,大家对产品优化的一些建议和意见进行了相应的优化和修复,同时,还新增了一些令人激动的功能和插件. 下面先为大家介绍4.4版本中Smobiler的优化和修复: 优化 1, PageView ...

  7. C# 判断用户是否对路径拥有访问权限

    如何获取当前系统用户对文件/文件夹的操作权限? 1.获取安全信息DirectorySecurity DirectorySecurity fileAcl = Directory.GetAccessCon ...

  8. Oracle 11g设置IP访问限制

    出于数据安全考虑,对Oracle数据库的IP做一些限制,只有固定的IP才能访问. 修改$ORACLE_HOME/network/ADMIN/sqlnet.ora文件 增加以下内容(红色表示注释): # ...

  9. EditPlus提示错误:找不到或无法加载主类

    问题:EditPlus提示错误:找不到或无法加载主类. 原因:换了另外一台电脑,忘了什么时候,环境变量被误删了. 解决问题: 1.检查文件名和public修饰的类名是否一致. 2.文件查看时,有没有隐 ...

  10. python多线程爬虫+批量下载斗图啦图片项目(关注、持续更新)

    python多线程爬虫项目() 爬取目标:斗图啦(起始url:http://www.doutula.com/photo/list/?page=1) 爬取内容:斗图啦全网图片 使用工具:requests ...