the django travel(two)分页

一:django路由系统:

注意:我们在urls.py中 定义url的时候,可以加$和不加$,区别的是:加$正则匹配的时候,比如:'/index/$'只能匹配'/index/'这样的url 不能匹配'/index/1'。而不加$的可以进行模糊匹配的。

至于加不加 $由自己的需求来定。

 

a)在项目中路由默认配置在总项目下得urls.py文件中,如下:

 1 from django.conf.urls import url
 2 from django.contrib import admin
 3 from ops import views
 4 urlpatterns = [
 5     # url(r'^admin/', admin.site.urls),
 6     url(r'^login/', views.login),
 7     url(r'^regis/', views.regis),
 8     url(r'^home/', views.home),
 9     url(r'^menu/', views.menu),
10     url(r'^jquery/', views.jquery),
11     url(r'^hostinfo/', views.host_son),
12     url(r'^detail/', views.detail),
13     url(r'^input/', views.input),
14     url(r'^delete/', views.delete),
15     url(r'^chan_pwd/', views.chan_pwd),
16     url(r'', views.login),
17 ]

 当客户端连接到达django底层的socket时候,通过这个路由表。来匹配客户端的url。匹配(正则匹配)顺序从上到下,依次匹配,遇到匹配的url,停止匹配。django通过反射来实现,将用户的请求给views.py模块对应的函数来处理,函数将客户端的请求

处理之后,并返回给客户端结果,可以是一个跳转(redirect)也可以是返回一个字符串(HttpResponse),也可以是携带变量和页面(render)。

当然我也可以设置一个默认的url,当上面所有的都不匹配的url转发到默认url:

1  url(r'', views.login),

上面默认将不匹配的url转发到登录页面。

b)动态路由。

需求场景:

1:比如说博客园中:

上图中我们可以看见分页中,如果页数很多,我们不能对每个页面写一个url,这不实际,那怎么办呢?通过正则表达式来实现动态路由。

比如上面的分页我们可以这么写:

1 url(r'^user_list/(\d+)$', views.user_list),

如上url,通过正则(\d+)来匹配一个数字。来实现匹配多个url族。由后端函数user_list来处理。

1 def user_list(request,uid):
2     print(uid)
3     return HttpResponse(uid)

 

如url,当请求进来的时候,会自动将后面的(\d+)的值传给user_list函数。

2:关于分页:

1 def user_list(reuqest):
2     page=request.GET.get('page')    
3     return HttpResponse(page) 

 

注意:当我们get请求的时候,比如url如:http://127.0.0.1:8000/hostinfo/?page=1 。?page=1 我们可以通过:request.GET.get('page') 获取page这个变量。分页就是采用这个功能来实现。

3:动态url传入多个参数?

1 url(r'^user_list/(\d+)/(\d+)$', views.user_list),

 

后面函数接收的时候,多个参数接收,他们一一对应的,需要注意!参数之间用/隔开。

1 def user_list(request,uid,uid1):
2     print(uid)
3     return HttpResponse(uid+uid1)

 

4:动态url传递key:value形式:

原理是通过正则表达式来实现:

1  url(r'^user_list/(?P<v1>\d+)/(?P<V2>\d+)$', views.user_list),

 

?p<v1>表示后面的数字的key值为v1。后面的函数接收参数需要写成key形式。

1 def user_list(request,v1,v2):
2     print(v1,v2)
3     return HttpResponse(v1+v2)

 

这种的情况下,变量的位置可以随意,这个是通过key值来获取前端传的参数。

5:路由分级

当我们的子程序越来越多的情况下,把所有的url放在一个配置文件中,显着很笨拙也很不容易管理。所以有url分级。通过前端urls.py文件转到后面的子程序urls.py的程序。进行转发。

   url(r'^app01/', include("app01.urls")),

app01是我们注册的子程序。然后在app01下创建我们的urls.py文件。可以通过:hostip:port/app01/index  or  hostip:port/app01/login进行访问。

 三:Ajax数据提交:

ajax是基于jquey的封装的,可以在页面不刷新的情况下,进行后台数据提交验证,常用于非表单的提交的、用户名和密码验证等。

code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/font-awesome-4.6.3/css/font-awesome.min.css">
    <link rel="stylesheet" href="/static/css/menu/menu.css">
    <link rel="short icon" href="/static/img/6.png">
{#    <link rel="stylesheet" href="/static/css/bootstrap.min.css">#}
    {% block css %}
    {% endblock %}
</head>
<body>
    <div class="pd_header">
        <span>主机管理后台</span>
       <a href="/login/"><button class="ko">账号注销</button></a>
{#        <div class="ok">登录用户:{{ username}}</div>#}
        <div style="clear: both;"></div>
    </div>
    <div class="menu">
        <div class="body">
            <p class="menu2" onclick="showmen(this);"><i class="fa fa-desktop left" aria-hidden="true"></i>
                主机管理<i class="fa fa-angle-double-down a" aria-hidden="true"></i></p>
            <div class="hide b">
            <p class="d">
                <i class="fa fa-angle-right c" aria-hidden="true"></i>
                <a id="1" style="border: 0"  href="/hostinfo/?page=1">主机信息</a>
            </p>
            <p><i class=" fa fa-angle-right c" aria-hidden="true"></i>
                <a id="2" style="border: 0" href="/home/?page=1" >信息修改</a></p>
            </div>
        </div>
        <div class="body">
            <p class="menu2" onclick="showmen(this)"><i class="fa fa-apple left" aria-hidden="true"></i>
                资产管理 <i class="fa fa-angle-double-down a" aria-hidden="true"></i></p>
            <div class="hide b">
            <p class="d"> <i class="fa fa-angle-right c" aria-hidden="true"></i>
                <a id="3"  style="border: 0" href="/input/" >资产录入</a></p>
            <p><i class="fa fa-angle-right c" aria-hidden="true"></i>
                <a id="4" style="border: 0" href="#" >xx</a></p>
            </div>
        </div>
        <div class="body">
            <p class="menu2" onclick="showmen(this)"> <i class="fa fa-user left" aria-hidden="true"></i>
                用户管理 <i class="fa fa-angle-double-down a" aria-hidden="true"></i></p>
            <div class="hide b">
            <p class="d"><i class="fa fa-angle-right c" aria-hidden="true"></i>
                <a id="5" style="border: 0" href="/chan_pwd/" >密码修改</a></p>
            <p class="d"><i class="fa fa-angle-right c " aria-hidden="true"></i>
                <a id="6" style="border: 0" href="#" >待定</a></p>
            </div>
        </div>
    </div>
    <div class="pd_content">
     {% block content %} {% endblock %}
    {% block div_page %} {% endblock %}
    </div>

    <script src="/static/js/homejs/jquery-1.12.4.js"></script>
    {% block js  %}
    {% endblock %}
    <script>
        function showmen(obj){

            $(obj).next().removeClass('hide');
            $(obj).parent().siblings().find('.b').addClass('hide');
        }
        function CheckVal(ths){
            if ($('#test').val().length==0){
                var tag=document.createElement('div');
                tag.innerText='输入不能为空';
                $(ths).after(tag);
                return false
            }
        }
        function ShowMenu(ths){
            $('#1').parent().parent().removeClass('hide');
            $('#1').parent().addClass('active');
                }
        function RemoveS(ths){
            $(ths).siblings().remove('div')
            }
        function CatchInfo(ths){
            var id=$(ths).parent().siblings().first().text();
            $.ajax(
                    {
                        url:"/detail/",
                        type:"POST",
                        data:{
                            'id':id
                        }

                    }
            )
        }
        function Delete(ths){
            /*
            功能:该函数主要判断用户删除数据返回情况。
            */
            var a=[];
        $('input').each(
                function(){
                    if ($(this).prop('checked')){
                        var id=$(this).parent().next().text().trim();
                        $(this).parent().parent().remove();
                        $.ajax({
                            url:"/delete/",
                            type:"POST",
                            data:{"id":id},
                            success:function(data){
                                if(data=='1'){
                                    a.push(data)

                                }else {
                                    a.push('2')
                                }
                            }
                        })
                    }
                }
        );
            if($.inArray('2',a)==-1){
                console.log(a);
               alert("删除成功!!");
            }

    }
        function Comm_Data(ths){
            var b=[];
            $('input[type=checkbox]').each(
              function(i){
                  var a=[];
                  if ($(this).prop('checked')){
                      $(this).parent().siblings().each(
                              function(){
                                  if($(this).attr('edit')){
                                      console.log($(this).children().val());
                                      a.push($(this).children().val())
                                  }
                              }

                      );
                      console.log(a);
                      $.ajax(
                              {
                                  url:'/home/',
                                  type:'POST',
                                  traditional :true,
                                  data:{"uu":a},
                                  success:function(data){
                                    if (data=='1') {
                                        b.push('1')
                                    }else {
                                        b.push('2')
                                    }
                                  }
                              }
                      )
                  }
              }
            );
            if ($.inArray('2',b)==-1){
                console.log(b);
                alert('数据更新成功!')
            }
        }
    {% block js1 %}
    {% endblock %}
    </script>
</body>
</html>

其中:

 1         function Delete(ths){
 2             /*
 3             功能:该函数主要判断用户删除数据返回情况。
 4             */
 5             var a=[];
 6         $('input').each(
 7                 function(){
 8                     if ($(this).prop('checked')){
 9                         var id=$(this).parent().next().text().trim();
10                         $(this).parent().parent().remove();
11                         $.ajax({
12                             url:"/delete/",/*提交的url,即向哪个url提交数据。
13                             type:"POST",/*提交数据的方法。
14                             data:{"id":id},/*提交的数据类型。注意是字典形式。
15                             success:function(data){/*data是后台返回的数据,success后面的函数,是提交数据之后接收后端数据进行操作的函数。自动执行。可以在这里进行判断后台是否正确处理我们的请求。
16                                 if(data=='1'){
17                                     a.push(data)
18 
19                                 }else {
20                                     a.push('2')
21                                 }
22                             }
23                         })
24                     }
25                 }
26         );
27             if($.inArray('2',a)==-1){
28                 console.log(a);
29                alert("删除成功!!");
30             }
31 
32     } 

注意的是:success:function(data){}中的data是后台返回的数据如果是render返回的页面 那data就是文件的字符串页面如果是HttpResponse,那data就是接收的字符串。

后端接收:接收数组的时候需要getlist:request.POST.getlist('uu')

 1 def home(request):
 2     '''
 3     功能:该函数主要功能是后台修改数据页面。
 4     :param request:
 5     :return:返回用户请求信息。
 6     '''
 7     if request.method=='GET':
 8         count=Hostinfo.objects.all().count()
 9         page_po=request.GET.get('page',None)
10         page_obj=div_page.Pager(page_po)
11         start=page_obj.start
12         end=page_obj.end
13         page=page_obj.page_str(count,'/home/')
14         host_obj=Hostinfo.objects.all()[start:end]
15         return render(request, 'host_mod_son.html',{'data':host_obj,'page_str':page})
16     # return render(request, 'host_mod_son.html',{'data':host_obj,'page_str':page})
17     elif request.method=='POST':
18         update_list=request.POST.getlist('uu')
19         print(update_list)
20         id=update_list[0]
21         hostname=update_list[1]
22         ip=update_list[2]
23         status=update_list[3]
24         host_info=Hostinfo.objects.filter(id=id)
25         if hostname!=host_info[0].host:
26             Hostinfo.objects.filter(id=id).update(host=hostname)
27         if  ip !=host_info[0].ip:
28             Hostinfo.objects.filter(id=id).update(ip=ip)
29         if  status !=host_info[0].stat:
30             Hostinfo.objects.filter(id=id).update(stat=status)
31         return  HttpResponse('1')

 

注意:当我们用ajax传数组的时候需要加入:traditional :true,

 1                       $.ajax(
 2                               {
 3                                   url:'/home/',
 4                                   type:'POST',
 5                                   traditional :true,/*传递数组的时候使用。
 6                                   data:{"uu":a},
 7                                   success:function(data){
 8                                     if (data=='1') {
 9                                         b.push('1')
10                                     }else {
11                                         b.push('2')
12                                     }
13                                   }
14                               }
15                       ) 

多条数据提交:

<script>
        function Ajaxsubmit(){
            var array_users = [
                {'username':'evil','weight':18},
                {'username':'liu','weight':18},
                {'username':'evil_liui','weight':18},

            ];
            $.ajax({
                url:"/ajax_mdata/",
                type:'POST',
                data:{data:array_users},
                success:function(arg){

                }
            })
        }
    </script>

上面只是简单的返回数据,为了返回的数据更规范化:

 1 import json
 2 
 3 def ajax_data(request):
 4     ret = {'status':True,'error':''}
 5     try:
 6         print request.POST
 7     except Exception,e:
 8         ret['status'] = False
 9         ret['error'] = str(e)
10     #在上面如果他出错我就把他ret[status] = False
11     return HttpResponse(json.dumps(ret))

html:

 1 <script>
 2         function Ajaxsubmit(){
 3             var array_users = [
 4                 {'username':'evil','arg':18},
 5                 {'username':'liu','arg':18},
 6                 {'username':'evil_liu','arg':18},
 7 
 8             ];
 9             $.ajax({
10                 url:"/ajax_mdata/",
11                 type:'POST',
12                 tradition: true,
13                 data:{data:JSON.stringify(array_users)},
14                 success:function(arg){
15                     var callback_dict = $.parseJSON(arg);//这里把字符串转换为对象
16                     //然后咱们就可以判断
17                     if(callback_dict){//执行成功了
18                         //简单测试
19                         alert('提交成功')
20                     }else{//如果为False执行失败了
21                         alert(callback_dict.error)
22                     }
23 
24                 }
25             })
26         }
27     </script>

 四:模板

1:母板:

如上的后台管理页面,点击左侧的菜单,无论点击那个子菜单,整个页面只有C部分进行变换,我们把A  B部分叫做母板,变化的C叫做子板。

我们创建一份母板,然后子板继承母板既可。以后不用在写母板部分的代码,类似有python中的模块导入的意思。

 母板:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <link rel="stylesheet" href="/static/css/font-awesome-4.6.3/css/font-awesome.min.css">
 7     <link rel="stylesheet" href="/static/css/menu/menu.css">
 8     <link rel="short icon" href="/static/img/6.png">
 9     {% block css %}
10     {% endblock %}
11 </head>
12 <body>
13     <div class="pd_header">
14         <span>主机管理后台</span>
15        <a href="/login/"><button class="ko">账号注销</button></a>
16         <div style="clear: both;"></div>
17     </div>
18     <div class="menu">
19         <div class="body">
20             <p class="menu2" onclick="showmen(this);"><i class="fa fa-desktop left" aria-hidden="true"></i>
21                 主机管理<i class="fa fa-angle-double-down a" aria-hidden="true"></i></p>
22             <div class="hide b">
23             <p class="d">
24                 <i class="fa fa-angle-right c" aria-hidden="true"></i>
25                 <a id="1" style="border: 0"  href="/hostinfo/?page=1">主机信息</a>
26             </p>
27             <p><i class=" fa fa-angle-right c" aria-hidden="true"></i>
28                 <a id="2" style="border: 0" href="/home/?page=1" >信息修改</a></p>
29             </div>
30         </div>
31         <div class="body">
32             <p class="menu2" onclick="showmen(this)"><i class="fa fa-apple left" aria-hidden="true"></i>
33                 资产管理 <i class="fa fa-angle-double-down a" aria-hidden="true"></i></p>
34             <div class="hide b">
35             <p class="d"> <i class="fa fa-angle-right c" aria-hidden="true"></i>
36                 <a id="3"  style="border: 0" href="/input/" >资产录入</a></p>
37             <p><i class="fa fa-angle-right c" aria-hidden="true"></i>
38                 <a id="4" style="border: 0" href="#" >xx</a></p>
39             </div>
40         </div>
41         <div class="body">
42             <p class="menu2" onclick="showmen(this)"> <i class="fa fa-user left" aria-hidden="true"></i>
43                 用户管理 <i class="fa fa-angle-double-down a" aria-hidden="true"></i></p>
44             <div class="hide b">
45             <p class="d"><i class="fa fa-angle-right c" aria-hidden="true"></i>
46                 <a id="5" style="border: 0" href="/chan_pwd/" >密码修改</a></p>
47             <p class="d"><i class="fa fa-angle-right c " aria-hidden="true"></i>
48                 <a id="6" style="border: 0" href="#" >待定</a></p>
49             </div>
50         </div>
51     </div>
52     <div class="pd_content">
53      {% block content %} {% endblock %}
54     {% block div_page %} {% endblock %}
55     </div>
56 
57     <script src="/static/js/homejs/jquery-1.12.4.js"></script>
58     {% block js  %}
59     {% endblock %}
60     </body>
61 </html>

 

子板:

 1 {% extends 'layout/menu.html' %}
 2 {% block content %}
 3     <div>
 4     <h3>数据录入</h3>
 5 </div>
 6     <form action="/input/" method="post">
 7         <table class="table2">
 8             <tr>
 9                 <th>IP</th>
10                 <th>port</th>
11                 <th>status</th>
12                 <th>hostname</th>
13             </tr>
14             <tr>
15                 <td><input lable="IP" onfocus="Remove(this)" name="IP" type="text" /></td>
16                 <td><input  lable="port" onfocus="Remove(this)" name="port" type="text" ></td>
17                 <td><input  lable="status" onfocus="Remove(this)" name="status" type="text"/></td>
18                 <td><input lable="hostname" onfocus="Remove(this)" name="hostname" type="text"/></td>
19             </tr>
20         </table>
21         <input type="submit" style="font-family:微软雅黑" onclick=" return Make(this)" value="提交数据" />
22         <p style="color: red;font-family:“微软雅黑">{{ messgae }}</p>
23     </form>
24 {% endblock %}
25 {% block js %}
26     <script src="/static/js/input.js"></script>
27 {% endblock %}
28 {% block js1 %}
29     function ShowMenu1(ths){
30     $('#3').parent().parent().removeClass('hide');
31     $('#3').parent().addClass('active');
32         }
33     ShowMenu1()
34 {% endblock %}

 

效果:

需要注意:

1:一个母板中,需要3个地方是由子板来进行自行定义的:

a:子板的CSS

b:子板的js

c:子板的内容。

继承的母板的语法:

1 {% extends 'layout/menu.html' %}

 

母板中的可被定义部门的书写方式:

1     {% block js  %}
2     {% endblock %}

 

子板可以根据母板定义的block块的名字进行引用:

1 {% block js %}
2     <script src="/static/js/input.js"></script>
3 {% endblock %}

规范:

我们可以创建一个include目录,下面创建需要的html文件,里面写上要导入的内容。

1 <h1>输入组合</h1>
2 <input type="text"/>
3 <input type="text"/>
4 <input type="text"/>
5 <input type="text"/>
6 <input type="text"/>

然后在html中导入

1 {% extends 'master/master_templates.html' %}
2 
3 {% block content %}
4     <h1>xxxxi</h1>
5     {% include 'include/simple_input.html' %}
6 {% endblock %}

五:分页:

分页思想:

1:需要考虑每页需要展示多少条数据。

2:一共多少条数据,需要多少页。

3:每个页面展示多少页脚。

4:如果当前页小于页面展示的页脚,该怎么去展示。

代码:

 1 #!/usr/bin/env python
 2 #-*- coding:utf-8 -*-
 3 #evil_liu
 4 from django.utils.safestring import mark_safe
 5 
 6 class Pager():
 7     '''
 8     功能:该类是实现分页功能。
 9     '''
10     def __init__(self,current_page):
11         self.current_page = int(current_page)
12     #把方法伪造成属性(1)
13     @property
14     def start(self):
15         return (self.current_page-1)*10
16     @property
17     def end(self):
18         return self.current_page*10
19 
20     def page_str(self,all_item,base_url):
21         '''
22         功能:该函数是对分页计算以及字符串的拼接。
23         :param all_item: 数据库中数据条目总数。
24         :param base_url: 分页请求url。
25         :return: 返回分页的字符串变量。
26         '''
27         all_page, div = divmod(all_item, 10)
28 
29         if div > 0:
30             all_page += 1
31 
32         pager_list = []
33 
34         if all_page <= 10:
35             start = 1
36             end = all_page
37         else:
38             if self.current_page <= 5:
39                 start = 1
40                 end = 10 + 1
41             else:
42                 start = self.current_page - 5
43                 end = self.current_page + 6
44                 if self.current_page + 6 > all_page:
45                     start = all_page - 10
46                     end = all_page + 1
47 
48         #把页面动态起来传入起始和结束
49         for i in range(start, end):
50 
51             #判断是否为当前页
52             if i == self.current_page:
53                 temp = '<a style="color:red;font-size:26px;padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)
54             else:
55                 temp = '<a style="padding: 5px" href="%s?page=%d">%d</a>' % (base_url,i,i)
56 
57             # 把标签拼接然后返回给前端
58             pager_list.append(temp)
59 
60         #上一页
61         if self.current_page > 1:
62             pre_page = '<a href="%s?page=%d">上一页</a>' % (base_url, self.current_page - 1)
63         else:
64             # javascript:void(0) 什么都不干
65             pre_page = '<a href="javascript:void(0);">上一页</a>'
66         #下一页
67         if self.current_page >= all_page:
68             next_page = '<a href="javascript:void(0);">下一页</a>'
69         else:
70             next_page = '<a href="%s?page=%d">下一页</a>' % (base_url, self.current_page + 1)
71 
72         pager_list.insert(0, pre_page)
73         pager_list.append(next_page)
74 
75         return mark_safe("".join(pager_list))

 

posted @ 2016-09-09 18:24  evil_liu  阅读(294)  评论(0编辑  收藏  举报