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. scrapy在pycharm配置启动(无需命令行启动)

    一.新建文件 run.py这个名字随意哈 方法一. from scrapy.cmdline import execute execute(['scrapy','crawl','爬虫程序名字','-a' ...

  2. 关于mybtis 使用过程中发生There is no getter for property named 'id' in class 'java.lang.String' 错误

    今天在修改一个关于mybtis语句时,偶然发现的一个错误  There is no getter for property named 'id' in class 'java.lang.String' ...

  3. Easy User Manager System writeup

    0x01 解题 思路 一个进程用自己的ip去申请拿到code然后进入verify页面,另外一个进程去申请8.8.8.8 步骤 1. 首先注册一个账号 然后用两个不同的浏览器进入Change页面.这里我 ...

  4. php 7.1.32 +Apache 2.4 配置 (x64)

    最近phpstudy 后门事件一出,吓得小编瑟瑟发抖,决心自己配置环境不再用集成环境. 一.apache 配置 首先我们先去apache 官网下载apache apache2.4地址:https:// ...

  5. Java后端,最全知识点

    你可能有所感悟.零散的资料读了很多,但是很难有提升.到处是干货,但是并没什么用,简单来说就是缺乏系统化.另外,噪音太多,雷同的框架一大把,我不至于全都要去学了吧. 这里,根据基础.Java基础.Jav ...

  6. 微信小程序拒绝授权后重新拉起授权窗口

    问题: 在首次进入小程序时,我们常常会收到一些获取权限的申请,比如「获取地理位置权限」.需要微信登录时请求「获得你的公开信息(昵称.头像等)」.对于这些权限申请,开发者当然希望获得所有权限,而用户拒绝 ...

  7. Octave-CostFunction

    假设 X= [1 1;1 2;1 3] y = [1;2;3] theta = [0;0] costFunction J : function J = costFunction(X,y,theta) ...

  8. Quasar framework 配置vue apollo

    Quasar 整合 vue-apollo 确保你已经知道quasar 和 vue apollo 在quasar中使用vue apollo客户端时出现的一点小问题 在quasar项目中使用vue-apo ...

  9. canvas详解----绘制线条

    <!DOCTYPE html> <html> <head> <title>canvas详解</title> </head> &l ...

  10. cf之kmp匹配稍稍改一改

    看样例就知道要干嘛了 http://codeforces.com/contest/1200/problem/E 每次我们用新的串和答案串匹配,答案串的匹配位置是max(0,(int)ans.size( ...