Django:阶段总结、Ajax与分页器

本文目录:

一、路由控制

二、视图层

三、模板层

四、模型层、单表操作、多表操作

五、什么是ajax

六、分页器组件

 

一、路由控制

  补充点(什么是web应用?)

  网站:BS架构应用程序:B是浏览器  S:server(实现了wsgi协议)+application(我们都在写这个),其实就是CS

  MVC和MTV(django)

    -M:model跟数据库打交道

    -T:Templates模板层,对到mvc的是V这一层

    -V:视图Views路由+V是MVC的c

  web框架:

    application拆分

    a:server b:映射关系  c:模板渲染

    Flask:

    Django

    Tornado

  1.Django中路由的作用

    请求的路径跟视图函数的映射关系

  2.简单的路由配置

    四个参数:第一个正则表达式,第二个函数内存地址,第三个默认值,第四个是别名

  3.分组

    无名:(正则表达式)值分出来当关键字参数传到视图函数

    有名:(?P<名字>正则表达式)值分出来当关键字参数传到视图函数

  4.路由分发

    url(r‘^app01/’,include('app01,urls'))

  5.反向解析

    就是根据别名,取到对应的url地址

      -视图层:reverse('别名'args=())

      -模板层:{% url ‘别名’ 参数 参数 %}

  6.名称空间

    -include(‘app01.urls’,namespance=‘app01’)

    -以后再反向解析:reverse(‘app01:别名’args=())

  7.Django2.0版的path

    -path:路径是准确路径,不是正则表达式了

    -内置了5个转换器

    -自定义转换器

二、视图层

  1.视图函数

  2.HttpResponse对象

    -GET

    -POST

    -FILES

    -path

    -method

    -get_full_path()

    -body

  3.HttpResponse

    -三件套

  4.JsonResponse

    -HttpResponse+json  

  5.CBV和FBV

    -基于类的视图:

      -url配置 类名.as_view()

      -views.py

        class Test(View)

          dispatch:总的分发方法

          def get(self,request)

            return HttpRequest对象

  6.简单文件上传

    -前端页面:form-data

    -视图层:FILES(字典)根据Key值取出来,拿到文件对象

  问题:POST请求是否可以在请求路径中参加参数?可以,从GET中取

    -反向解析传参

      举例:在模板层反向解析出要删除的图书路径

      -url(r'^dlbook/(?P<pk>\d+)',view.deletebook,name='deletebook'),

      -<td><a href="{% url'deletebook' book.pk %}">删除</a></td>

 

三、模板层

 

  1.模板简介

    模板语言

  2.模板语法之变量

    -基本用法{{ 变量名 }}

    -深度查询

    {{ 对象.方法 }} 方法不能传参数

    -字典,列表 用.

  3.模板之过滤器

    -data

    -dafault

    -slice

    ...

  4.模板之标签

    {% for %}
      {% for a in 可迭代对象 %}
        {{ a.name }}
        {{ forloop }}
      {% endfor %}
    {% if 条件%}
    {% elif条件 %}
    {% else %}
    {% endif %}

    {% with %}:取别名

 

  5.自定义标签和过滤器

    1.确认app是否已经过期

    2.在app下创建一个包:templatetags

    3.在包中写mytag.py

    4.from django.template import LIbrary

    5.register=Library()

    6.标签:

@register.simple_tag(别名)
def mytesttag(a,b,c)
    return a+b+c

 

     过滤器

@register.filter(别名)
def mytestfilter(别名)
  return a+b

    7.使用标签

{% load mytag %}
标签
{% mytesttag 参数1,参数2,参数3... %}
过滤器
{{ 第一个参数|mytestfilter:'第二个参数' }}

  

  6.模板导入和继承  

    -导入{% include ‘在模板中定义盒子’ %}

    -继承

     

 -先写一个母版,在模板中定义盒子
      {% block content %}
        {% endblock %}
      -使用:
        在其他模板中:
        {% extends % 'base.html'}        
        {% block content %}
        写变化的内容
        {% endblock %}
      {{ block.super }} 会把原来的母版中的内容拿过来

 

四、模型层、单表操作、多表操作

  -单表:基本查询,双下划线的模糊查询

  -多表:

    基于对象的跨表

    基于双下划线的多表

    聚合查询

      -聚合函数使用

    F,Q查询

      F可以去除字段的值

      Q查询:构造出与或非的关系

    分组查询:

 '''
    group by谁就以谁做基表
    filter在前表示where
    filter在后表示having
    values在前表示group by 的字段
    values在后表示取值
'''
 #查询每个出版社的名称和书籍个数               

     

五、什么是ajax

  通过js语言跟后台进行交互的一个东西

    -特点;异步,局部刷新

# 后台views.py

from django.shortcuts import render, HttpResponse


# Create your views here.
def index(request):
    if request.method == 'GET':
        return render(request, 'index.html')

# 前台index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="/static/jquery-3.3.1.js"></script>
    <title>Title</title>
</head>
<body>
<button id="btn">点我向后台发数据</button>
<span id="sp"></span>
<p><button id="btn2">点我</button></p>


<br>
<input type="text" id="first">+<input type="text" id="second">=<input type="text" id="sum"><button id="btn3">计算</button>
</body>

<script>
      $('#btn2').click(function () {
          alert(2222)
      })
    $('#btn').click(function () {
        {#alert(1)#}
        //往后台提交数据,jquery封装的方法
        $.ajax({
            'url':'/test/',    //请求的路径
            'type':'get',  //请求的方法
            success:function (data) {
                //data 是后台返回的数据
                console.log(data)

                $("#sp").text(data)
            }
        })
    })

    $("#btn3").click(function () {
        /**
        var first=$("#first").val()
        var second=$("#second").val()
        var sum=first+second
        $ ("#sum").value(sum)
         **/
        $.ajax({
            url:'/sum/?aa=123',
            type:'post',
            data:{first:$("#first").val(),second:$("#second").val()},
            success:function(data){
                //alert(data)

                $("#sum").val(data)
            }

        })
    })



</script>
</html>

 

案例要求:

  1 后台返回json格式
   2 问?返回render,返回redirect?
 
 基于ajax写一个登陆功能,一旦登陆成功,跳转到百度,登陆失败,在页面显示用户名或密码错误

 

 

# views.py

from django.shortcuts import render, HttpResponse


# Create your views here.
def index(request):
    if request.method == 'GET':
        return render(request, 'index.html')


def test(request):
    if request.method == 'GET':
        import time
        # time.sleep(10)
        return HttpResponse('hello web')

import json
from django.http import JsonResponse
def login(request):
    dic={'status':100,'msg':None}
    if request.method == 'GET':
        return render(request, 'login.html')
    # if request.is_ajax():
    if request.method=='POST':
        name=request.POST.get('name1')
        pwd=request.POST.get('pwd2')
        if name=='lqz' and pwd=='123':
            dic['msg'] = '登陆成功'
            # 想让前端跳转
            # dic['url']='http://www.baidu.com'
            dic['url']='/test/'
        else:
            # 返回json格式字符串
            dic['status']=101
            dic['msg']='用户名或密码错误'
        # return JsonResponse(dic)
        return HttpResponse(json.dumps(dic))



def loginjson(request):
    dic={'status':100,'msg':None}
    if request.method=='POST':
        print(request.POST)
        print(request.GET)
        print(request.body)
        xx=request.body.decode('utf-8')
        # re是个字典{"name1":"lqz","pwd2":"123"}
        re=json.loads(xx)
        request.POST=11


        print(request.POST)
        #
        #
        # name=re.get('name1')
        # pwd=re.get('pwd2')
        # print(name)
        # print(pwd)
        return HttpResponse('ok')

 

#login登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="/static/jquery-3.3.1.js"></script>
    <title>登陆</title>
</head>
<body>
{#<form action="" method="post">#}



    <p>用户名:<input type="text"  id="name"></p>
    <p>密码:<input type="password" id="pwd"></p>
{#    这里不能这么写了#}
{#    <input type="submit" value="提交1">#}
{#    <button>提交2</button>#}
    <input type="button" value="提交3" id="submit"><span id="error"></span>
    <input type="button" value="提交json格式" id="submit1"><span id="error"></span>

{#</form>#}
</body>

<script>

    $('#submit').click(function () {
        $.ajax({
            url:'/login/',
            type:'post',
            data:{name1:$("#name").val(),pwd2:$("#pwd").val()},
            success:function (data) {
                //后台用JsonResponse返回数据
                //data 就会被转成字典
                console.log(data)
                console.log(typeof data)
                //JSON.parse(data) 把字符串类型转成字典
                data=JSON.parse(data)
                {#JSON.stringify()#}
                console.log(typeof dat1)
                if(data.status == 100){
                    //成功,跳转到指定页面
                    //location.href=地址,前端就会跳转到指定的url
                    alert(data.msg)
                    //$("#error").text(data.msg+'正在跳转')
                    //location.href=data.url
                }else{
                    $("#error").text(data.msg)
                }


            }
        })
    })
    $('#submit1').click(function () {
        postdata={name1:$("#name").val(),pwd2:$("#pwd").val()}
        $.ajax({
            url:'/loginjson/',
            type:'post',
            //指定提交的编码格式是json格式,
            //contentType:'application/json',
            //data:JSON.stringify(postdata),
            //data:postdata,
            data:'123',
            success:function (data) {
                console.log(data)

            }
        })
    })

</script>
</html>

 

六、分页器组件

1.Django中的分页器组件

  在显示页面中的分页数据,需要用到django中的分页器组件

  导入:from django.core.paginator import Paginator

Paginator对象:    paginator = Paginator(user_list, 10)
# per_page: 每页显示条目数量
# count:    数据总个数
# num_pages:总页数
# page_range:总页数的索引范围,如: (1,10),(1,200)
# page:     page对象    
page对象:page=paginator.page(1)
# has_next              是否有下一页
# next_page_number      下一页页码
# has_previous          是否有上一页
# previous_page_number  上一页页码
# object_list           分页之后的数据列表
# number                当前页
# paginator             paginator对象

 

2.view视图层

from django.shortcuts import render,HttpResponse

# Create your views here.
from app01.models import *
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

def index(request):

    '''
    批量导入数据:

    Booklist=[]
    for i in range(100):
        Booklist.append(Book(title="book"+str(i),price=30+i*i))
    Book.objects.bulk_create(Booklist)
    '''

    '''
分页器的使用:

    book_list=Book.objects.all()

    paginator = Paginator(book_list, 10)

    print("count:",paginator.count)           #数据总数
    print("num_pages",paginator.num_pages)    #总页数
    print("page_range",paginator.page_range)  #页码的列表



    page1=paginator.page(1) #第1页的page对象
    for i in page1:         #遍历第1页的所有数据对象
        print(i)

    print(page1.object_list) #第1页的所有数据


    page2=paginator.page(2)

    print(page2.has_next())            #是否有下一页
    print(page2.next_page_number())    #下一页的页码
    print(page2.has_previous())        #是否有上一页
    print(page2.previous_page_number()) #上一页的页码



    # 抛错
    #page=paginator.page(12)   # error:EmptyPage

    #page=paginator.page("z")   # error:PageNotAnInteger

    '''


    book_list=Book.objects.all()

    paginator = Paginator(book_list, 10)
    page = request.GET.get('page',1)
    currentPage=int(page)


    try:
        print(page)
        book_list = paginator.page(page)
    except PageNotAnInteger:
        book_list = paginator.page(1)
    except EmptyPage:
        book_list = paginator.page(paginator.num_pages)


    return render(request,"index.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})

 

3.模板层

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" 
    integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>

<div class="container">

    <h4>分页器</h4>
    <ul>

        {% for book in book_list %}
             <li>{{ book.title }} -----{{ book.price }}</li>
        {% endfor %}

     </ul>


    <ul class="pagination" id="pager">
         {% if book_list.has_previous %}
            <li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li>
         {% else %}
            <li class="previous disabled"><a href="#">上一页</a></li>
         {% endif %}


         {% for num in paginator.page_range %}

             {% if num == currentPage %}
               <li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li>
             {% else %}
               <li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li>

             {% endif %}
         {% endfor %}



         {% if book_list.has_next %}
            <li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li>
         {% else %}
            <li class="next disabled"><a href="#">下一页</a></li>
         {% endif %}
    </ul>
</div>



</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" 
    integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>

<div class="container">

    <h4>分页器</h4>
    <ul>

        {% for book in book_list %}
             <li>{{ book.title }} -----{{ book.price }}</li>
        {% endfor %}

     </ul>


    <ul class="pagination" id="pager">
         {% if book_list.has_previous %}
            <li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li>
         {% else %}
            <li class="previous disabled"><a href="#">上一页</a></li>
         {% endif %}


         {% for num in paginator.page_range %}

             {% if num == currentPage %}
               <li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li>
             {% else %}
               <li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li>

             {% endif %}
         {% endfor %}



         {% if book_list.has_next %}
            <li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li>
         {% else %}
            <li class="next disabled"><a href="#">下一页</a></li>
         {% endif %}
    </ul>
</div>



</body>
</html>

 

4.扩展

'''
    显示左5,右5,总共11个页,
    1 如果总页码大于11
        1.1 if 当前页码减5小于1,要生成1到12的列表(顾头不顾尾,共11个页码)
            page_range=range(1,12)
        1.2 elif 当前页码+5大于总页码,生成当前页码减10,到当前页码加1的列表(顾头不顾尾,共11个页码)
            page_range=range(paginator.num_pages-10,paginator.num_pages+1)
        1.3 else 生成当前页码-5,到当前页码+6的列表
            page_range=range(current_page_num-5,current_page_num+6)
    2 其它情况,生成的列表就是pageinator的page_range
        page_range=paginator.page_range

'''

核心逻辑

 

试图

def index(request):


    book_list=Book.objects.all()

    paginator = Paginator(book_list, 15)
    page = request.GET.get('page',1)
    currentPage=int(page)

    #  如果页数十分多时,换另外一种显示方式
    if paginator.num_pages>11:

        if currentPage-5<1:
            pageRange=range(1,11)
        elif currentPage+5>paginator.num_pages:
            pageRange=range(currentPage-5,paginator.num_pages+1)

        else:
            pageRange=range(currentPage-5,currentPage+5)

    else:
        pageRange=paginator.page_range


    try:
        print(page)
        book_list = paginator.page(page)
    except PageNotAnInteger:
        book_list = paginator.page(1)
    except EmptyPage:
        book_list = paginator.page(paginator.num_pages)


    return render(request,"index.html",locals())

 

例子:

  视图层

def page_test(request):
    # book_list=[]
    # for i in range(100):
    #     book=Book(name='book%s'%i,price=10+i,pub_date='2018-09-18',publish_id=1)
    #     book_list.append(book)
    # Book.objects.bulk_create(book_list,10)
    book_list=Book.objects.all()
    # 生成paginator对象,传入书籍列表,每页10条数据
    paginator=Paginator(book_list,3)
    # 总页码数
    print(paginator.num_pages)
    # 页码列表
    print(paginator.page_range)
    # 总数据
    print(paginator.count)
    # 获取页面传来的页码
    current_page=int(request.GET.get('page',1))
    page_range=[]
    # 左5 右5

    # 获取页面传来的页码的page对象
    try:
        page=paginator.page(current_page)
        # print(page.has_next())            #是否有下一页
        # print(page.next_page_number())    #下一页的页码
        # print(page.has_previous())        #是否有上一页
        # print(page.previous_page_number()) #上一页的页码
        # 循环打印出当页对象
        for i in page:
            print(i)
    except Exception as e:
        current_page=1
        page = paginator.page(1)
    if paginator.num_pages>11:
        if current_page+5>paginator.num_pages:
            page_range=range(paginator.num_pages-10,paginator.num_pages+1)
        elif current_page-5<1:
            page_range=range(1,12)
        else:
            page_range=range(current_page-5,current_page+6)
    else:
        page_range=paginator.page_range



    return render(request,'page_test.html',locals())
viewsdef page_test(request):
    # book_list=[]
    # for i in range(100):
    #     book=Book(name='book%s'%i,price=10+i,pub_date='2018-09-18',publish_id=1)
    #     book_list.append(book)
    # Book.objects.bulk_create(book_list,10)
    book_list=Book.objects.all()
    # 生成paginator对象,传入书籍列表,每页10条数据
    paginator=Paginator(book_list,3)
    # 总页码数
    print(paginator.num_pages)
    # 页码列表
    print(paginator.page_range)
    # 总数据
    print(paginator.count)
    # 获取页面传来的页码
    current_page=int(request.GET.get('page',1))
    page_range=[]
    # 左5 右5

    # 获取页面传来的页码的page对象
    try:
        page=paginator.page(current_page)
        # print(page.has_next())            #是否有下一页
        # print(page.next_page_number())    #下一页的页码
        # print(page.has_previous())        #是否有上一页
        # print(page.previous_page_number()) #上一页的页码
        # 循环打印出当页对象
        for i in page:
            print(i)
    except Exception as e:
        current_page=1
        page = paginator.page(1)
    if paginator.num_pages>11:
        if current_page+5>paginator.num_pages:
            page_range=range(paginator.num_pages-10,paginator.num_pages+1)
        elif current_page-5<1:
            page_range=range(1,12)
        else:
            page_range=range(current_page-5,current_page+6)
    else:
        page_range=paginator.page_range



    return render(request,'page_test.html',locals())

  

  模板层

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <title>Title</title>
</head>
<body>

<ul>

    {% for foo in page %}
        <li>{{ foo.name }}</li>

    {% endfor %}

</ul>
<nav aria-label="Page navigation">
    <ul class="pagination">
        {% if page.has_previous %}
            <li>
                <a href="/page_test/?page={{ page.previous_page_number }}" aria-label="Previous">
                    <span aria-hidden="true">上一页</span>
                </a>
            </li>
        {% else %}
            <li class="disabled">
                <a href="#" aria-label="Previous">
                    <span aria-hidden="true">上一页</span>
                </a>
            </li>
        {% endif %}

        {% for foo in page_range %}
            {% if current_page == foo %}
                <li class="active"><a href="/page_test/?page={{ foo }}">{{ foo }}</a></li>
            {% else %}
                <li><a href="/page_test/?page={{ foo }}">{{ foo }}</a></li>
            {% endif %}

        {% endfor %}
        {% if page.has_next %}
            <li>
                <a href="/page_test/?page={{ page.next_page_number }}" aria-label="Next">
                    <span aria-hidden="true">下一页</span>
                </a>
            </li>
        {% else %}
            <li class="disabled">
                <a href="#" aria-label="Next">
                    <span aria-hidden="true">下一页</span>
                </a>
            </li>

        {% endif %}

    </ul>
</nav>


</body>
</html>

模版

引用出处:https://www.cnblogs.com/liuqingzheng/articles/9509767.html

  1.后端如果返回JsonResponse,前端的ajax内部会自动将json格式字符串转换成字典

  2.后端如果返回HttpResponse,前端的ajax内部不会自动给你转换,拿到的data是字符串形式,需要手动JSON.parse(data)来转成字典

  3.字符串转字典:JSON.parse(data)

   字典转字符串:aa=JSON.stringify(字典对象)

  4.如果前端传的格式是JSON,django不会处理body中的内容,需要自己处理

   只有前端传的格式是urlencoded,form-data格式,django才会给我处理
总结:
posted @ 2019-01-18 00:19  仗剑煮大虾  阅读(176)  评论(0编辑  收藏  举报