1.分页

  web必备的功能

  1)批量制造测试数据

    定义一个空列表用于存储 orm对象 ,models.表名(字段=...)创建orm对象append到列表 ,使用bulk_create(对象列表)一次性提交 ,避免了多次与数据库连接损耗

#脚本加载django环境
import os if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled.settings")
import django django.setup()
from crm import models
from django.db import transaction
DepObjList = []
for i in range(1,300):
obj = models.Dep(name='部门{}'.format(i))
print(obj)
DepObjList.append(obj)
models.Dep.objects.bulk_create(DepObjList)

  2)分页明确所需要的数据

    后端分页的减轻数据库压力

    per_num =  每页最大显示的页码数(自定义一个值如 20 50)

    all_count = 一共有多少条数据需要展示(所有数据对象列表.count())

    max_show = 底部页码栏展示的长度 (这里有左极值和右极值 ,以及访问页码时保证当前页码在中间显示)

    half_show = 底部页码栏展示的一半是多少max_show // 2

    page_num = 当前访问的页码 (根据该页码展示数据)

    total_num = 页码的总数

    start      #根据当前访问的页码计算开始切片的索引

    end       #根据当前访问的页码计算结束切片的索引

    page_html    #生成底部页码的标签返回html页面

  3)放在list视图函数中 ,因为前端的逻辑不太好写 ,所以将逻辑放在后端写 ,生成的标签通过mark_safe()转换为浏览器可解析的无需前端加safe    

    实现的点

      (1)页码长度为固定值max_show ,且该值位于中心 ,左右有half_show的长度页码 (3 4 5 6 7 8 9 10 11 12 13 )  选中8那么3-7和9-13就是half_show的长度!!

        (2)   页码总数total_num小于max_show的情况下

      (3)页码左极值不允许出现负值 ,如果按照中心定值那么一定会出现 (-2 -1 0 1 2 4 5 6 7 8  )选中3那么出现了负数页码 !! 改进当选中小于half_show的长度固定 1-max_show的页码

      (4)页码右极值不允许出现超过total_num的值 ,如果按照中心定值会出现超出total_num的页码数 ! !改进当选中大于total_num-half_show ,长度固定 total_num减max_show - total_num页码

        (5)   页码无极值问题情况下

        (6)   每页根据当前页码 ,将对象列表切片显示本页码的数据

        (7)   由于前段逻辑判断不好写, 放在后端写页码的li标签,其中当页码等于1或最后一页的时候需要禁止两侧按钮 ,放入列表拼接字符串转为安全代码传给前端展示

def deplist(request):
all_obj = models.Dep.objects.all()
per_num = 10
all_count = all_obj.count()
max_show = 11
half_show = max_show // 2 # 当前访问的页面默认是1 ,如果url上有访问的page那么使用request.GET的参数
page_num = 1
if request.GET.get('page'):
page_num = int(request.GET.get('page')) total_num = all_count // per_num
# 最后一页的数据可能不够per_num那也需要展示 所以总页码数再加1
if all_count % per_num != 0:
total_num += 1 """
    限制底部页码长度 ,保证左右极值不会小于1 大于total_num ,并且保证长度
如点击标签8 ,那么保证8在中间 ,前后分别增加5个标签 ,《3 4 5 6 7 8 9 10 11 12 13》
"""# 当页码不足定义好的最长的时候 ,有多长显示多长
if total_num < max_show:
page_start = 1
page_end = total_num
# 当页码足够多的时候 ,考虑左右极值的情况处理
else:
# 左极值!如果访问页码小于 页码预设半长 ,那么直接显示1-max_show
if page_num <= half_show:
page_start = 1
page_end = max_show
# 右极值!访问如果超过了total_num - half_show那么显示total_num-max_show到total_num这个固定长度
elif page_num > total_num - half_show:
page_start = total_num - max_show+1
page_end = total_num
# 无极值情况下
else:
page_start = page_num - half_show
page_end = page_num + half_show """
切片(规律)的到start与end索引值
1页展示数据 msg:[0:30]
2页展示数据 msg:[30:60]
...
page_num展示数据 msg:[(page_num - 1) * per_num : page_num * per_num]
"""
start = (page_num - 1) * per_num
end = page_num * per_num page_li_list = []
if page_num == 1:
page_li_list.append(
'<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>') else:
page_li_list.append(
'<li ><a href="?page={}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>'.format(
page_num - 1
)) for i in range(page_start, page_end + 1):
if i == page_num:
page_li_list.append('<li class="active"><a href="?page={}">{}</a></li>'.format(i, i))
else:
page_li_list.append('<li><a href="?page={}">{}</a></li>'.format(i, i)) if page_num == total_num:
page_li_list.append(
'<li class="disabled"><a href="#" aria-label="Next"><span aria-hidden="true">&raquo;</span></a>')
else:
page_li_list.append(
'<li ><a href="?page={}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a>'.format(page_num + 1)
) page_html = ''.join(page_li_list) return render(request, 'deplist.html',
{'msg': all_obj[start:end], 'page_html': mark_safe(page_html)})

2.分页使用类实现复用

  定义一个类

####定义文件Pageination.py

"""
使用方法:
在逻辑中引用实例化对象,一般来说page_num = request.GET.get('page',1) all_count=models...all().count()
在返回值中调用start与end方法获取到切片的索引! """
class Pageination: def __init__(self, page_num, all_count, per_num=20, max_show=11, ): # 当前访问页码值
try:
self.page_num = int(page_num)
except Exception as e:
self.page_num = 1 # 数据总条数
self.all_count = all_count # 每页最大显示数据条数
self.per_num = per_num # 每页底部页码长度
self.max_show = max_show
self.half_show = self.max_show // 2 # 计算页码总量 ,divmod方法 ,返回两个参数的 整除数 ,取余数,分别用两个参数接收
self.total_num, more = divmod(self.all_count, self.per_num)
# total_num就是总共的页码数
if more != 0:
self.total_num += 1 # 根据页码生成给数据切片的索引
@property # 方法调用变属性
def start(self):
return (self.page_num - 1) * self.per_num @property # 方法调用变属性
def end(self):
return self.page_num * self.per_num # 根据页码页码底部html标签
@property # 方法调用变属性
def page_html(self):
# 限制起始值与终止值 ,当页码不足max_show ,那就直接将最大页码去显示
if self.total_num < self.max_show:
page_start = 1
page_end = self.total_num
else:
# 左极值:防止负页码 ,当页码数小于5 就不要放把5中间了直接1-最大显示了
if self.page_num <= self.half_show:
page_start = 1
page_end = self.max_show # 右极值:防止显示页码数大于页码总数 ,当某个页码数 ,该页码数的后面加上half_show超过了总页码数
elif self.page_num + self.half_show > self.total_num:
# 我们将页码开始显示为总页码数减去每次显示的最大数 +1 获得了最后允许显示的开始值
page_start = self.total_num - self.max_show + 1
# 将最大页码数作为结束值
page_end = self.total_num
else:
page_start = self.page_num - self.half_show
page_end = self.page_num + self.half_show # 将前端标签一个个追加到列表中(上翻-所有页码-下翻),加完之后统一生成一个str传到前端展示
page_li_list = [] # 上翻制作-本页码为1,则禁用(bootstrap样式)
if self.page_num == 1:
page_li_list.append(
'<li class="disabled"><a href="" aria-label="Next"><span aria-hidden="true">&laquo;</span></a></li>')
# 页码不是1的都可以上翻页(bootstrap样式)
else:
page_li_list.append(
'<li><a href="?page={}" aria-label="Next"><span aria-hidden="true">&laquo;</span></a></li>'.format(
self.page_num - 1)) # 将本次展示的页码<li>标签全部加入字典中
for i in range(page_start, page_end + 1):
# 如果该页码就是访问的页码加上一个(bootstrap样式)
if i == self.page_num:
page_li_list.append('<li class="active"><a href="?page={}">{}</a></li>'.format(i, i))
else:
page_li_list.append('<li><a href="?page={}">{}</a></li>'.format(i, i)) # 下翻制作-点击页码为最后一个页码,则禁用(bootstrap样式)
if self.page_num == self.total_num:
page_li_list.append(
'<li class="disabled"><a href="" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>')
# 页码不是最后页的都可以下翻页(bootstrap样式)
else:
page_li_list.append(
'<li><a href="?page={}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>'.format(
self.page_num + 1)) # 将列表内容拼接成一个字符串,也就是很多的li标签HTML代码 ,直接返回给前端
return ''.join(page_li_list)

  实例化引用

def deplist(request):
all_obj = models.Dep.objects.all()
pageobj = Pageination(request.GET.get('page', 1), all_obj.count())
return render(request, 'deplist.html',
{'msg': all_obj[pageobj.start:pageobj.end], 'page_html': mark_safe(pageobj.page_html)})

3.crm数据补充

  部门表,人员表的逻辑完成 , 新增班级表+课程表+校区表 ,其中班级表中外键课程和校区 ,多对多到人员表

  问题1:多对多的表中 ,拥有mantomany字段的表会出现显示关系管理对象问题  解决1:在model中定义一个方法返回关系管理对象中所有对象名字 ,前端执行这个方法显示

  问题2:前端显示时间的问题使用date: 'Y-m-d'解决

##models
class ClassList(models.Model):
"""班级表 其中任课老师与班级是多对多的"""
...... def __str__(self):
return str(self.semester) def show_teachers(self):
return ','.join([i.name for i in self.teachers.all()]) ##html
<td>{{ obj.start_date|date:'Y-m-d' }}</td>
<td>{{ obj.graduate_date|date:'Y-m-d' }}</td>
<td>{{ obj.show_teachers }}</td>

  补充班级相关增删改查逻辑 (edit与add整合为change)

#####url
url(r'^class/list/', classes.classes_list, name='classes_list'),
url(r'^class/add/', classes.classes_change, name='classes_add'),
url(r'^class/edit/(\d+)', classes.classes_change, name='classes_edit'),
url(r'^class/del/(\d+)', classes.classes_del, name='classes_del'), #####models
class Course(models.Model):
"""课程名"""
name = models.CharField(max_length=32) def __str__(self):
return self.name class School(models.Model):
"""校区名"""
name = models.CharField(max_length=32) def __str__(self):
return self.name class ClassList(models.Model):
"""班级表 其中任课老师与班级是多对多的"""
school = models.ForeignKey('School', verbose_name='校区名')
course = models.ForeignKey('Course', verbose_name='课程表')
semester = models.IntegerField(verbose_name='班级')
price = models.IntegerField(verbose_name='价格')
start_date = models.DateField(verbose_name='开班日期')
graduate_date = models.DateField(verbose_name='结业日期', null=True, blank=True)
tutor = models.ForeignKey(verbose_name='班主任', to='User', related_name='classes')
teachers = models.ManyToManyField(verbose_name='任课老师', to='User', related_name='teach_classes')
memo = models.CharField(verbose_name='说明', max_length=255, blank=True, null=True) def __str__(self):
return str(self.semester) def show_teachers(self):
return ','.join([i.name for i in self.teachers.all()]) #####modelform class ClassFrom(forms.ModelForm):
class Meta:
model = models.ClassList
fields = '__all__' def __init__(self, *args, **kwargs):
super(ClassFrom, self).__init__(*args, **kwargs)
for field in self.fields.values():
print(field)
field.widget.attrs.update({'class': 'form-control'}) #####view from django.shortcuts import render, reverse, redirect, HttpResponse
from crm import models
from crm.modleforms import ClassFrom def classes_list(request):
all_class = models.ClassList.objects.all()
return render(request, 'classes_list.html', {'msg': all_class}) def classes_change(request, edit_id=None):
obj = models.ClassList.objects.filter(pk=edit_id).first()
form_obj = ClassFrom(instance=obj)
if request.method == 'POST':
form_obj = ClassFrom(request.POST, instance=obj)
if form_obj.is_valid():
form_obj.save()
return redirect(reverse('crm:classes_list'))
return render(request, 'depadd-edit.html', {'form_obj': form_obj}) def classes_del(request, del_id):
obj = models.ClassList.objects.filter(pk=del_id).delete()
return redirect(reverse('crm:classes_list')) #####edit.hrml
{% extends 'layout.html' %}
{% block content %}
<div class="container col-lg-4 col-md-offset-3" style="margin-top: 30px;">
<form class="form-horizontal" method="post" novalidate>
{% csrf_token %}
{% for obj in form_obj %}
<div class="form-group {% if obj.errors %}has-error{% endif %}">
<label for="{{ obj.id_for_label }}"
class="col-sm-2 control-label">{{ obj.label }}</label>
<div class="col-sm-10">
{{ obj }}
<span class="help-block has-error">{{ obj.errors.0 }}</span>
</div>
</div>
{% endfor %}
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">保存</button>
</div>
</form>
</div>
{% endblock %} #####list.html
{% extends 'layout.html' %}
{% load static %}
{% block js %}
<script src="{% static '/js/sweetalter.js' %}"></script>
<script> $('.b1').click(function () { swal({
title: "提示",
text: "删除后无法恢复",
icon: "warning",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
let del_id = $(this).attr('del_id');
if (willDelete) {
$.ajax({
url: '/crm/dep/del/' + del_id,
type: 'get',
success: () => {
swal("已删除!", {
icon: 'success',
});
$(this).parent().parent().remove()
}
});
} else {
swal("取消删除!");
}
});
})
</script>
{% endblock %}
{% block content %}
<table class="text-center table table-striped table-bordered" style="margin-top: 20px">
<tr>
<td>序号</td>
<td>id</td>
<td>部门</td>
<td>描述</td>
<td>操作</td>
</tr>
{% for obj in msg %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ obj.pk }}</td>
<td>{{ obj.name }}</td>
<td>{{ obj.desc }}</td>
<td><a href={% url 'crm:depedit' obj.pk %}><i class="fa fa-pencil-square-o" aria-hidden="true">&nbsp&nbsp&nbsp</i></a>
<a class="b1" del_id="{{ obj.pk }}" style="color: red"><i class=" fa fa-remove"
aria-hidden="true"></i></a></td>
</tr>
{% endfor %}
</table> <nav aria-label="Page navigation">
<ul class="pagination">
{{ page_html }}
</ul>
</nav> {% endblock %}

  

crm-2的更多相关文章

  1. Enterprise Solution 3.1 企业应用开发框架 .NET ERP/CRM/MIS 开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    行业:基于数据库的制造行业管理软件,包含ERP.MRP.CRM.MIS.MES等企业管理软件 数据库平台:SQL Server 2005或以上 系统架构:C/S 开发技术 序号 领域 技术 1 数据库 ...

  2. SAP CRM 性能小技巧

    导言 本页面打算收集SAP CRM实施中可以用于避免性能问题的注意事项,重要的事项会由图标标识. 如果你有其他的技巧想要说出来,别犹豫! 性能注意事项 通用 缓存读取类访问,特别是在性能关键的地方,比 ...

  3. SAP CRM 树视图(TREE VIEW)

    树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...

  4. SAP CRM 用户界面对象类型和设计对象

    在CRM中的用户界面对象类型的帮助下,我们可以做这些工作: 进行不同的视图配置 创建动态导航 从设计层控制字段标签.值帮助 控制BOL对象的属性的可视性 从导航栏访问自定义组件 一个用户界面对象类型之 ...

  5. SAP CRM 显示消息/在消息中进行导航

    向用户展示消息,在任何软件中都是十分重要的. 在SAP CRM WEB UI中展示消息,不是一项很难的任务,只需要创建消息并在之后调用方法来显示它 消息类和消息号: 我在SE91中创建了如下的消息类和 ...

  6. Dynamics CRM 2015-Data Encryption激活报错

    在CRM的日常开发中,Data Encryption经常是不得不开启的一个功能.但是有时,我们可能遇到一种情况,Organization导入之后,查看Data Encryption是已激活的状态,但是 ...

  7. SAP CRM 客户控制器与数据绑定

    当用户从视图离开时,视图将失去它的数据.解决这个问题,需要引入客户控制器(Custom Controller)(译者注:SAP CRM客户端中,不同地方的Custom Controller会翻译为“客 ...

  8. SAP CRM BOL编程基础,代码+详细注释

    网络上可以找到一些使用BOL查询.维护数据的DEMO,但几乎都是单纯的代码,缺乏说明,难以理解.本文除了代码外,还给出了详细的注释,有助于理解BOL编程中的一些基本概念. 这是一篇翻译的文章,你可能会 ...

  9. SAP CRM 通过调试观察CL_CRM_BOL_ENTITY中的数据

    这个(BOL里面)最重要的类值得一看. BOL中的每条记录都会在CL_CRM_BOL_ENTIT中表示.至今,我们已经写过一些事件处理器,并且我们已经直接或间接的通过这个类工作.在业务场景中,我们也许 ...

  10. SAP CRM 7.0中的BOL(Business Object Layer)

    业务对象层(BOL)和通用交互层(GenIL)属于业务层. 业务对象层:   在CRM WebClient会话运行期间,业务对象层存储业务对象的数据以及它们属性和关系的定义. 通用交互层 通用交互层将 ...

随机推荐

  1. java 实现文件下载中文名不显示

    需要将指定字符串的编码转换成浏览器里面的ISO-8859-1编码 String name = new String(name.getBtes("utf-8"),"ISO- ...

  2. Ruby中星号打包解包操作

    Ruby中可以使用一个星号*和两个星号**完成一些打包.解包操作,它们称为splat操作符: 一个星号:以数组为依据进行打包解包(参考文章) 两个星号:以hash为依据进行打包解包(参考文章) 两个星 ...

  3. Java每日一面(Part1:计算机网络)[19/11/02]

    作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 1.TCP的滑动窗口 1.1 RTT和RTO的区别 ​ RTT:发送一个数据包到收到对应的ACK,所花费的时间 ​ RTO:重传时间间隔,TCP在发 ...

  4. 自学_DOM<五>

    类库DOM DOM(document object medol)文档对象模型. DOM就是HTML页面的模型,将每个标签都做为一个对象,JavaScript通过调用DOM中的属性.方法就可以对网页中的 ...

  5. GO基础之函数的高级用法

    一.可变参数 支持可变长参数列表的函数可以支持任意个传入参数,比如fmt.Println函数就是一个支持可变长参数列表的函数. package main import "fmt" ...

  6. ES6变量的解构赋值(一)数组的解构赋值

    let[a,...arr]=[1,2,3,4];//a==>1 arr==>[2,3,4] let [x, y, ...z] = ['a'];//a==>'a' y==>und ...

  7. 如何获取数据泵dm和dw进程的 Strace (Doc ID 1411563.1)

    How To Get A Strace Of The Data Pump dm And dw Process(es) (Doc ID 1411563.1) APPLIES TO: Oracle Dat ...

  8. [靶场实战]:SQL注入-显错注入

    SQL注入的本质:就是将用户输入的数据当作代码带入执行. 注入条件: 1.用户能控制输入 2.能够将程序原本执行的代码,拼接上用户输入的数据进行执行 首先检查是否存在注入点 Rank1: 构造语句 ? ...

  9. android binder 进程间通信机制3-Binder 对象生死

    以下概述Binder通信过程中涉及到的四个对象:Binder本地对象.Binder实体对象.Binder引用对象.Binder代理对象的生死. 1.Binder通信的交互过程 1.Client 进程发 ...

  10. May 19th, 2019. Week 21st, Sunday

    Fight for what matters to you. 为自己珍视的东西奋斗吧! We all want to make our life goals true, and we all expe ...