Day20-初识Ajax

Posted momo8238

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day20-初识Ajax相关的知识,希望对你有一定的参考价值。

 

想要实现的功能:点击提交以后,让数据发到后台进行验证,但是页面不刷新。悄悄提交用Ajax.

那么返回的字符串怎么样展示到前端html页面呢?可以在HTML中写个标签,定义一个选择器。

利用$(\'#id\').text=(JSON.parse(data).error) 来赋值进而展示到页面上。

 

AJAX 教程

 

AJAX = Asynchronous javascript and XML(异步的 JavaScript 和 XML)。

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行

 

Ajax $--就是jquery
 $.ajax({
  url:\'/host\', #提交到哪里
  type:"post", #以什么方式提交
  data:{\'k1\':123,\'k2\':\'root\'}, #提交的内容
  success:function(data){      #匿名函数,回调函数,收到客户端的回应后才会执行。
   //data是服务器端返回的字符串
   var obj=JSON.parse(data);
  }
 })

 

1.在host.html中先写1个标签,id="ajax_submit",增加“悄悄提交”的功能

display:inline-block是什么呢?相信大家对这个属性并不陌生,根据名字inline-block我们就可以大概猜出它是结合了inline和block两者的特性于一身,简单的说:设置了inline-block属性的元素既拥有了block元素可以设置width和height的特性,又保持了inline元素不换行的特性

 

2.给这个标签绑定事件

里面写明了:要提交到哪里,以什么方式提交,以及提交的内容。还有回调函数(后台返回的数据,放在data中),即:收到test_ajax客户端的回应后才会执行。如果验证成功,则刷新页面;否则,弹出1条告警信息。$--就是jquery

 

 

3.后台在views.py中写一个函数

 

4.增加路由条目

 

效果:做了验证

 

粘贴部分程序:

urls.py-------增加了test_ajax的路由条目

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r\'^admin/\', admin.site.urls),
    url(r\'^business/\', views.business),
    url(r\'^host/\', views.host),
    url(r\'^test_ajax/\',views.test_ajax),
]

 views.py

from django.shortcuts import render,HttpResponse,redirect
from app01 import models
# Create your views here.

def business(request):
    v1 = models.Business.objects.all()
    #QuerySet类型,里面存放的是对象。[obj(id,caption,code),obj,obj]

    v2 = models.Business.objects.all().values(\'id\',\'caption\')
    # QuerySet类型,里面存放的是字典[{\'id\':1,\'caption\':\'运维部\'},{\'id\':1,\'caption\':\'开发部\'}..]

    v3 = models.Business.objects.all().values_list(\'id\', \'caption\')
    # QuerySet类型,里面存放的是元组[(1,\'运维部\'),(2,\'开发部\').....]

    return render(request,\'business.html\',{\'v1\':v1,\'v2\':v2,\'v3\':v3})

# def host(request):
#     v1=models.Host.objects.filter(nid__gt=0) #nid>0,其实代表的是所有数据
#     # for row in v1:
#     #     print(row.b)
#     #     print(row.b.caption,row.b.code,sep=\'\\t\')
#     # return HttpResponse("Host")
#     v2 = models.Host.objects.filter(nid__gt=0).values(\'nid\',\'hostname\',\'b_id\',\'b__caption\')
#     #QuerySet:[{}]
#     for row in v2:
#         print(row[\'nid\'],row[\'hostname\'],row[\'b_id\'],row[\'b__caption\'])
#
#     v3 = models.Host.objects.filter(nid__gt=0).values_list(\'nid\', \'hostname\', \'b_id\', \'b__caption\')
#
#     return render(request, \'host.html\', {\'v1\': v1,\'v2\':v2,\'v3\':v3})


def host(request):
    if request.method==\'GET\':
        v1=models.Host.objects.filter(nid__gt=0) #nid>0,其实代表的是所有数据
        v2 = models.Host.objects.filter(nid__gt=0).values(\'nid\',\'hostname\',\'b_id\',\'b__caption\')
        v3 = models.Host.objects.filter(nid__gt=0).values_list(\'nid\', \'hostname\', \'b_id\', \'b__caption\')
        b_list=models.Business.objects.all()
        return render(request, \'host.html\', {\'v1\': v1,\'v2\':v2,\'v3\':v3,\'b_list\':b_list})
    elif request.method==\'POST\':
        h=request.POST.get(\'hostname\')
        i = request.POST.get(\'ip\')
        p = request.POST.get(\'port\')
        b = request.POST.get(\'b_id\')
        models.Host.objects.create(hostname=h,ip=i,port=p,b_id=b)
        return redirect(\'/host/\')

def test_ajax(request):
    h = request.POST.get(\'hostname\')
    i = request.POST.get(\'ip\')
    p = request.POST.get(\'port\')
    b = request.POST.get(\'b_id\')
    if h and len(h)>5:
        models.Host.objects.create(hostname=h, ip=i, port=p, b_id=b)
        return HttpResponse(\'OK\')
    else:
        return HttpResponse(\'主机名太短了\')

 models.py

from django.db import models
# Create your models here.

class Business(models.Model):
    #id列,是自动创建的
    caption=models.CharField(max_length=32)
    code=models.CharField(max_length=32)

class Host(models.Model):
    nid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32,db_index=True) #加上索引,可以提高查询速度
    ip=models.GenericIPAddressField(protocol="ipv4",db_index=True)
    port=models.IntegerField()
    b=models.ForeignKey("Business",to_field=\'id\')

host.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .hide{
            display:none;
        }
        .shade{
            position:fixed;
            top:0;
            bottom:0;
            right:0;
            left:0;
            background:black;
            opacity:0.6;
            z-index:100;
        }
        .add-modal{
            position:fixed;
            height:300px;
            width:400px;
            top:100px;
            left:50%;
            z-index:101;
            border:1px solid red;
            background:white;
            margin-left:-200px;
        }
    </style>
</head>
<body>
    <h1>主机列表(对象)-business</h1>
    <div>
        <input id="add_host" type="button" value="添加"/>

    </div>
    <table border="1">
        <thead>
            <tr>
                <th>序号</th>
                <th>主机名</th>
                <th>IP</th>
                <th>端口</th>
                <th>业务线名称</th>
            </tr>
        </thead>
        <tbody>
            {% for row in v1%}
            <tr hid="{{row.nid}}" bid="{{row.b_id}}">
                <td>{{forloop.counter}}</td>
                <td>{{row.hostname}}</td>
                <td>{{row.ip}}</td>
                <td>{{row.port}}</td>
                <td>{{row.b.caption}}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

    <h1>主机列表(字典)-business</h1>
    <table border="1">
        <thead>
            <tr>
                <th>主机名</th>
                <th>业务线名称</th>
            </tr>
        </thead>
        <tbody>
            {% for row in v2%}
            <tr hid="{{row.nid}}" bid="{{row.b_id}}">
                <td>{{row.hostname}}</td>
                <td>{{row.b__caption}}</td>
            </tr>
            {% endfor %}

        </tbody>
    </table>

    <h1>主机列表(元组)-business</h1>
    <table border="1">
        <thead>
            <tr>
                <th>主机名</th>
                <th>业务线名称</th>
            </tr>
        </thead>
        <tbody>
            {% for row in v3%}
            <tr hid="{{row.0}}" bid="{{row.2}}">
                <td>{{row.1}}</td>
                <td>{{row.3}}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

    <div class="shade hide"></div>
    <div class="add-modal hide">
        <form method="POST" action="/host/">
            <div class="group">
                <input id="host" type="text" placeholder="主机名" name="hostname"/>
            </div>

            <div class="group">
                <input id="ip" type="text" placeholder="IP" name="ip"/>
            </div>

            <div class="group">
                <input id="port" type="text" placeholder="端口" name="port"/>
            </div>

            <div class="group">
                <select id="sel" name="b_id">
                    {% for op in b_list %}
                    <option value="{{op.id}}">{{op.caption}}</option>
                    {% endfor %}

                </select>
            </div>

            <input type="submit" value="提交"/>
            <a id="ajax_submit" style="display:inline-block;padding:5px;background:blue;color:white">悄悄提交</a>
            <input id="cancel" type="button" value="取消"/>
        </form>
    </div>


    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        $(function(){
            $(\'#add_host\').click(function(){
                $(\'.shade,.add-modal\').removeClass(\'hide\');
            });
        $(\'#cancel\').click(function(){
            $(\'.shade,.add-modal\').addClass(\'hide\');
            });

        $(\'#ajax_submit\').click(function(){
            $.ajax({
                url:\'/test_ajax/\',
                type:\'POST\',
                data:{\'hostname\':$(\'#host\').val(),\'ip\':$(\'#ip\').val(),\'port\':$(\'#port\').val(),\'b_id\':$(\'#sel\').val()},
                success:function(data){
                    if(data=="OK"){location.reload()}
                    else{alert(data);}
                }
            })
        })
    })
    </script>

</body>
</html>

 business.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>业务线列表(对象)-business</h1>
    {% for row in v1 %}
        <li>{{row.id}} - {{row.caption}} - {{row.code}}</li>
    {% endfor %}

    <h1>业务线列表(字典)-business</h1>
    {% for row in v2 %}
        <li>{{row.id}} - {{row.caption}}</li>
    {% endfor %}

    <h1>业务线列表(元组)-business</h1>
    {% for row in v3 %}
        <li>{{row.0}} - {{row.1}}</li>
    {% endfor %}
</body>
</html>

 本节笔记

 

 

 

Ajax $--就是jquery
	$.ajax({
		url:\'/host\', #提交到哪里
		type:"post", #以什么方式提交
		data:{\'k1\':123,\'k2\':\'root\'}, #提交的内容
		success:function(data){      #匿名函数
			//data是服务器端返回的字符串
			var obj=JSON.parse(data);
		}
	})
	
	建议:永远让服务器端返回一个字典
	return HttpResponse(json.dumps(字典))

 修改程序,实现后台的悄悄验证

 

程序粘贴

views.py

from django.shortcuts import render,HttpResponse,redirect
from app01 import models
# Create your views here.

def business(request):
    v1 = models.Business.objects.all()
    #QuerySet类型,里面存放的是对象。[obj(id,caption,code),obj,obj]

    v2 = models.Business.objects.all().values(\'id\',\'caption\')
    # QuerySet类型,里面存放的是字典[{\'id\':1,\'caption\':\'运维部\'},{\'id\':1,\'caption\':\'开发部\'}..]

    v3 = models.Business.objects.all().values_list(\'id\', \'caption\')
    # QuerySet类型,里面存放的是元组[(1,\'运维部\'),(2,\'开发部\').....]

    return render(request,\'business.html\',{\'v1\':v1,\'v2\':v2,\'v3\':v3})

# def host(request):
#     v1=models.Host.objects.filter(nid__gt=0) #nid>0,其实代表的是所有数据
#     # for row in v1:
#     #     print(row.b)
#     #     print(row.b.caption,row.b.code,sep=\'\\t\')
#     # return HttpResponse("Host")
#     v2 = models.Host.objects.filter(nid__gt=0).values(\'nid\',\'hostname\',\'b_id\',\'b__caption\')
#     #QuerySet:[{}]
#     for row in v2:
#         print(row[\'nid\'],row[\'hostname\'],row[\'b_id\'],row[\'b__caption\'])
#
#     v3 = models.Host.objects.filter(nid__gt=0).values_list(\'nid\', \'hostname\', \'b_id\', \'b__caption\')
#
#     return render(request, \'host.html\', {\'v1\': v1,\'v2\':v2,\'v3\':v3})


def host(request):
    if request.method==\'GET\':
        v1=models.Host.objects.filter(nid__gt=0) #nid>0,其实代表的是所有数据
        v2 = models.Host.objects.filter(nid__gt=0).values(\'nid\',\'hostname\',\'b_id\',\'b__caption\')
        v3 = models.Host.objects.filter(nid__gt=0).values_list(\'nid\', \'hostname\', \'b_id\', \'b__caption\')
        b_list=models.Business.objects.all()
        return render(request, \'host.html\', {\'v1\': v1,\'v2\':v2,\'v3\':v3,\'b_list\':b_list})
    elif request.method==\'POST\':
        h=request.POST.get(\'hostname\')
        i = request.POST.get(\'ip\')
        p = request.POST.get(\'port\')
        b = request.POST.get(\'b_id\')
        models.Host.objects.create(hostname=h,ip=i,port=p,b_id=b)
        return redirect(\'/host/\')

def test_ajax(request):
    import json
    ret={\'status\':True,\'error\':None,\'data\':None}
    try:
        h = request.POST.get(\'hostname\')
        i = request.POST.get(\'ip\')
        p = request.POST.get(\'port\')
        b = request.POST.get(\'b_id\')
        if h and len(h)>5:
            models.Host.objects.create(hostname=h, ip=i, port=p, b_id=b)
        else:
            ret[\'status\']=False
            ret[\'error\']=\'太短了\'
    except Exception as e:
        ret[\'status\']=False
        ret[\'error\']=\'请求错误\'
    return HttpResponse(json.dumps(ret))

 host.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .hide{
            display:none;
        }
        .shade{
            position:fixed;
            top:0;
            bottom:0;
            right:0;
            left:0;
            background:black;
            opacity:0.6;
            z-index:100;
        }
        .add-modal{
            position:fixed;
            height:300px;
            width:400px;
            top:100px;
            left:50%;
            z-index:101;
            border:1px solid red;
            background:white;
            margin-left:-200px;
        }
    </style>
</head>
<body>
    <h1>主机列表(对象)-business</h1>
    <div>
        <input id="add_host" type="button" value="添加"/>

    </div>
    <table border="1">
        <thead>
            <tr>
                <th>序号</th>
                <th>主机名</th>
                <th>IP</th>
                <th>端口</th>
                <th>业务线名称</th>
            </tr>
        </thead>
        <tbody>
            {% for row in v1%}
            <tr hid="{{row.nid}}" bid="{{row.b_id}}">
                <td>{{forloop.counter}}</td>
                <td>{{row.hostname}}</td>
                <td>{{row.ip}}</td>
                <td>{{row.port}}</td>
                <td>{{row.b.caption}}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

    <h1>主机列表(字典)-business</h1>
    <table border="1">
        <thead>
            <tr>
                <th>主机名</th>
                <th>业务线名称</th>
            </tr>
        </thead>
        <tbody>
            {% for row in v2%}
            <tr hid="{{row.nid}}" bid="{{row.b_id}}">
                <td>{{row.hostname}}</td>
                <td>{{row.b__caption}}</td>
            </tr>
            {% endfor %}

        </tbody>
    </table>

    <h1>主机列表(元组)-business</h1>
    <table border="1">
        <thead>
            <tr>
                <th>主机名</th>
                <th>业务线名称</th>
            </tr>
        </thead>
        <tbody>
            {% for row in v3%}
            <tr hid="{{row.0}}" bid="{{row.2}}">
                <td>{{row.1}}</td>
                <td>{{row.3}}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

    <div class="shade hide"></div>
    <div class="add-modal hide">
        <form method="POST" action="/host/">
            <div class="group">
                <input id="host" type="text" placeholder="主机名" name="hostname"/>
            </div>

            <div class="group">
                <input id="ip" type="text" placeholder="IP" name="ip"/>
            </div>

            <div class="group">
                <input id="port" type="text" placeholder="端口" name="port"/>
            </div>

            <div class="group">
                <select id="sel" name="b_id">
                    {% for op in b_list %}
                    <option value="{{op.id}}">{{op.caption}}</option>
                    {% endfor %}

                </select>
            </div>

            <input type="submit" value="提交"/>
            <a id="ajax_submit" style="display:inline-block;padding:5px;background:blue;color:white">悄悄提交</a>
            <input id="cancel" type="button" value="取消"/>
            <span id="error_msg" style="color:red"></span>
        </form>
    </div>

    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        $(function(){
            $(\'#add_host\').click(function(){
                $(\'.shade,.add-modal\').removeClass(\'hide\');
            });
        $(\'#cancel\').click(function(){
            $(\'.shade,.add-modal\').addClass(\'hide\');
            });

        $(\'#ajax_submit\').click(function(){
            $.ajax({
                url:\'/test_ajax/\',
                type:\'POST\',
                data:{\'hostname\':$(\'#host\').val(),\'ip\':$(\'#ip\').val(),\'port\':$(\'#port\').val(),\'b_id\':$(\'#sel\').val()},
                success:function(data){
                    var obj=JSON.parse(data);
                    if(obj.status){location.reload();}
                    else{
                        $(\'#error_msg\').text(obj.error);
                    }
                }
            })
        })
    })
    </script>

</body>
</html>

 总结:用ajax进行验证的过程:

 

 

Ajax提交的过程:

 

1. Ajax是写在了host.html页面中。Ajax要提交的数据(想要验证的数据)也是来自于host.html中(当然了host.html中的数据是host函数从用户端获取到的,通过render传过来的);

 

 

 

2. urls.py中写上对应关系。url(r\'^test_ajax/\',views.test_ajax),

 

3. views.py下的ajax(request):函数会拿到这个数据,然后对这个数据进行check;      views.py下的ajax(request):也可以直接从views.py中拿数据进行check

 

4. check完了以后,会通过return HttpResponse 返回一个结果(必须是字符串格式)到host 下的Ajax中,触发Ajax中的success函数的执行。比如可以打印一句“检测通过”

 

1. return redirect对Ajax没有毛线用,Ajax只是发请求,整个页面是静态不会动的,哥就是不跳;所以用redirect没有用,前端也拿不到任何数据。

2. return render则是想渲染一点东西以后再返回给用户,假设返回一个HTML(其实是字符串)给用户了,那么我们的前端拿到以后,无法对它进行json.parse.要想执行json.parse,必须是形似列表或者字典的数据结构才可以。能不能用render,可以用,但是拿到它以后,用户无法对它进行进一步的操作,只能把它里面的字符串添加到host页面的某个标签下,因为无法对它进行json.parse的操作。

 

3. 可定制性更高的是用HttpResponse,我们可以让它返回任何数据,前端也好取。返回一个字典,然后前端想做什么就可以做什么了。可以写函数让它发生跳转。

 

1.在urls.py中写路由关系

url(r\'^test_ajax/\',views.test_ajax),

 

2.在views.py中写程序,服务器端进行判断然后给出回应。

def test_ajax(request):
    h = request.POST.get(\'hostname\')
    i = request.POST.get(\'ip\')
    p = request.POST.get(\'port\')
    b = request.POST.get(\'b_id\')
    if h and len(h)>5:
        models.Host.objects.create(hostname=h, ip=i, port=p, b_id=b)
        return HttpResponse(\'OK\')
    else:
        return HttpResponse(\'主机名太短了\')

 3.在host.html中写关联

 <a id="ajax_submit" style="display:inline-block;padding:5px;background:blue;color:white">悄悄提交</a>


        $(\'#ajax_submit\').click(function(){
            $.ajax({
                url:\'/test_ajax/\',
                type:\'POST\',
                data:{\'hostname\':$(\'#host\').val(),\'ip\':$(\'#ip\').val(),\'port\':$(\'#port\').val(),\'b_id\':$(\'#sel\').val()},
                success:function(data){
            //data是服务器端返回的字符串
                    if(data=="OK"){location.reload()}
                    else{alert(data);}

 

本节笔记:

			
Ajax $--就是jquery
	推荐使用下面这种方法
	$.ajax({
		url:\'/host\', #提交到哪里
		type:"post", #以什么方式提交
		data:{\'k1\':123,\'k2\':\'root\'}, #提交的内容
		success:function(data){      #匿名函数,回调函数,收到客户端的回应后才会执行。
			//data是服务器端返回的字符串
			var obj=JSON.parse(data); 转换成json对象
		}
	})
	
	建议:永远让服务器端返回一个字典
	return HttpResponse(json.dumps(字典))
	
	另外的这3种在内部调用的都是$.ajax方法。传的时候就不需要字典格式了。
	$.get(url="xx",data={},success=) 指明了以type=get的方法提交
	$.getJson
	$.post(url="xx",data={},success=) 指明了以type=post的方法提交

 

编辑一对多示例:增加编辑的功能

 

<input type="text" name="nid" style="display:none"/>   获取到编辑的是哪一行的数据,把行号获取到,不需要让用户看到。但是后台可以得到。        

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .hide{
            display:none;
        }
        .shade{
            position:fixed;
            top:0;
            bottom:0;
            right:0;
            left:0;
            background:black;
            opacity:0.6;
            z-index:100;
        }
        .add-modal,.edit-modal{
            position:fixed;
            height:300px;
            width:400px;
            top:100px;
            left:50%;
            z-index:101;
            border:1px solid red;
            background:white;
            margin-left:-200px;
        }
    </style>
</head>
<body>
    <h1>主机列表(对象)-business</h1>
    <div>
        <input id="add_host" type="button" value="添加"/>

    </div>
    <table border="1">
        <thead>
            <tr>
                <th>序号</th>
                <th>主机名</th>
                <th>IP</th>
                <th>端口</th>
                <th>业务线名称</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            {% for row in v1%}
            <tr hid="{{row.nid}}" bid="{{row.b_id}}">
                <td>{{forloop.counter}}</td>
                <td>{{row.hostname}}</td>
                <td>{{row.ip}}</td>
                <td>{{row.port}}</td>
                <td>{{row.b.caption}}</td>
                <td>
                    <a class="edit">编辑</a> | <a class="delete">删除</a>
                </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

    <h1>主机列表(字典)-business</h1>
    <table border="1">
        <thead>
            <tr>
                <th>主机名</th>
                <th>业务线名称</th>
            </tr>
        </thead>
        <tbody>
            {% for row in v2%}
            <tr hid="{{row.nid}}" bid="{{row.b_id}}">
                <td>{{row.hostname}}</td>
                <td>{{row.b__caption}}</td>
            </tr>
            {% endfor %}

        </tbody>
    </table>

    <h1>主机列表(元组)-business</h1>
    <table border="1">
        <thead>
            <tr>
                <th>主机名</th>
                <th>业务线名称</th>
            </tr>
        </thead>
        <tbody>
            {% for row in v3%}
            <tr hid="{{row.0}}" bid="{{row.2}}">
                <td>{{row.1}}</td>
                <td>{{row.3}}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>

    <div class="shade hide"></div>
    <div class="add-modal hide">
        <form method="POST" action="/host/">
            <div class="group">
                <input id="host" type="text" placeholder="主机名" name="hostname"/>
            </div>

            <div class="group">
                <input id="ip" type="text" placeholder="IP" name="ip"/>
            </div>

            <div class="group">
                <input id="port" type="text" placeholder="端口" name="port"/>
            </div>

            <div class="group">
                <select id="sel" name="b_id">
                    {% for op in b_list %}
                    <option value="{{op.id}}">{{op.caption}}</option>
                    {% endfor %}

                </select>
            </div>

            <input type="submit" value="提交"/>
            <a id="ajax_submit" style="display:inline-block;padding:5px;background:blue;color:white">悄悄提交</a>
            <input id="cancel" type="button" value="取消"/>
            <span id="error_msg" style="color:red"></span>
        </form>
    </div>

    <div class="edit-modal hide">
        <form id="edit_form" method="POST" action="/host/">
            <input type="text" name="nid" style="display:none"/>
            <input type="text" placeholder="主机名" name="hostname"/>
            <input type="text" placeholder="IP" name="ip"/>
            <input type="text" placeholder="端口" name="port"/>
            <select name="b_id">
                {% for op in b_list %}
                <option value="{{op.id}}">{{op.caption}}</option>
                {% endfor %}
            </select>
            <a id="ajax_submit_edit" style="display:inline-block;padding:5px;background:blue;color:white">确认编辑</a>

        </form>
    </div>
    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        $(function(){
            $(\'#add_host\').click(function(){
                $(\'.shade,.add-modal\').removeClass(\'hide\');
            });
        $(\'#cancel\').click(function(){
            $(\'.shade,.add-modal\').addClass(\'hide\');
            });

        $(\'#ajax_submit\').click(function(){
            $.ajax({
                url:\'/test_ajax/\',
                type:\'POST\',
                data:{\'hostname\':$(\'#host\').val(),\'ip\':$(\'#ip\').val(),\'port\':$(\'#port\').val(),\'b_id\':$(\'#sel\').val()},
                success:function(data){
                    var obj=JSON.parse(data);
                    if(obj.status){location.reload();}
                    else{
                        $(\'#error_msg\').text(obj.error);
                    }
                }
            })
        })

        $(\'.edit\').click(function(){
            $(\'.shade,.edit-modal\').removeClass(\'hide\');
            var bid=$(this).parent().parent().attr(\'bid\');
            var nid=$(this).parent().parent().attr(\'hid\');


            $(\'#edit_form\').find(\'select\').val(bid);
            $(\'#edit_form\').find(\'input[name="nid"]\').val(nid);
            //修改
            $.ajax({
                data:$(\'#edit_form\').serialize()
            });
            //models.Host.objects.filter(nid=nid).update()
        })
    })
    </script>

</body>
</html>

 

 

 

 

创建多对多示例

方式1:自定义关系表(想创建多少列就写多少列)

先创建一张Application的表,再创建一张hosttoapp表,做2表之间的关联。 

 

 

 

python manage.py makemigrations

python manage.py migrate

 

方式2:自动创建关系表,第3张表自动生成。(默认只能自动创建3列,无法加额外的数据),无法直接对第3张表进行操作。因为没有那个类。

 

 

但是可以对第3张表进行间接的操作

对第3张表进行间接操作的方法: 
obj=Application.objects.get(id=1)
obj.r.add(1) //增加application=1与host=1的1条对应关系
obj.r.add(2,3,4) //增加application=1与host=2,3,4的1条对应关系
obj.r.add(*[1,2,3,4]) //增加application=1与host=[1,2,3,4]的1条对应关系

obj.r.remove(1) //删除application=1与host=1的对应关系
obj.r.remove(2,4) //删除application=1与host=2,3的对应关系
obj.r.remove(*[1,2,3]) //删除application=1与host=[1,2,3]的对应关系

obj.r.clear() //清除application=1的下面的所有的对应关系

obj.r.set([3,5,7]) //相当于update,先把存在的数据都删除,再增加1-3,1-5,1-7的对应关系。

#所有相关的主机对象‘列表’,是QuerySet类型,不是真正的列表。obj.r后面可以跟的方法与application.objects.后面可跟的方法一样。
obj.r.all() //获取,obj.r 代表的是host对象。

 

创建一些数据备用

 

 

 

 

通过form表单实现提交,最终的效果:

 

粘贴部分程序:

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r\'^admin/\', admin.site.urls),
    url(r\'^business/\', views.business),
    url(r\'^host/\', views.host),
    url(r\'^test_ajax/\',views.test_ajax),
    url(r\'^app/\',views.app),
]

 

views.py

from django.shortcuts import render,HttpResponse,redirect
from app01 import models
# Create your views here.

def business(request):
    v1 = models.Business.objects.all()
    #QuerySet类型,里面存放的是对象。[obj(id,caption,code),obj,obj]

    v2 = models.Business.objects.all().values(\'id\',\'caption\')
    # QuerySet类型,里面存放的是字典[{\'id\':1,\'caption\':\'运维部\'},{\'id\':1,\'caption\':\'开发部\'}..]

    v3 = models.Business.objects.all().values_list(\'id\', \'caption\')
    # QuerySet类型,里面存放的是元组[(1,\'运维部\'),(2,\'开发部\').....]

    return render(request,\'business.html\',{\'v1\':v1,\'v2\':v2,\'v3\':v3})

# def host(request):
#     v1=models.Host.objects.filter(nid__gt=0) #nid>0,其实代表的是所有数据
#     # for row in v1:
#     #     print(row.b)
#     #     print(row.b.caption,row.b.code,sep=\'\\t\')
#     # return HttpResponse("Host")
#     v2 = models.Host.objects.filter(nid__gt=0).values(\'nid\',\'hostname\',\'b_id\',\'b__caption\')
#     #QuerySet:[{}]
#     for row in v2:
#         print(row[\'nid\'],row[\'hostname\'],row[\'b_id\'],row[\'b__caption\'])
#
#     v3 = models.Host.objects.filter(nid__gt=0).values_list(\'nid\', \'hostname\', \'b_id\', \'b__caption\')
#
#     return render(request, \'host.html\', {\'v1\': v1,\'v2\':v2,\'v3\':v3})


def host(request):
    if request.method==\'GET\':
        v1=models.Host.objects.filter(nid__gt=0) #nid>0,其实代表的是所有数据
        v2 = models.Host.objects.filter(nid__gt=0).values(\'nid\',\'hostname\',\'b_id\',\'b__caption\')
        v3 = models.Host.objects.filter(nid__gt=0).values_list(\'nid\', \'hostname\', \'b_id\', \'b__caption\')
        b_list=models.Business.objects.all()
        return render(request, \'host.html\', {\'v1\': v1,\'v2\':v2,\'v3\':v3,\'b_list\':b_list})
    elif request.method==\'POST\':
        h=request.POST.get(\'hostname\')
        i = request.POST.get(\'ip\')
        p = request.POST.get(\'port\')
        b = request.POST.get(\'b_id\')
        models.Host.objects.create(hostname=h,ip=i,port=p,b_id=b)
        return redirect(\'/host/\')

def test_ajax(request):
    import json
    ret={\'status\':True,\'error\':None,\'data\':None}
    try:
        h = request.POST.get(\'hostname\')
        i = request.POST.get(\'ip\')
        p = request.POST.get(\'port\')
        b = request.POST.get(\'b_id\')
        if h and len(h)>5:
            models.Host.objects.create(hostname=h, ip=i, port=p, b_id=b)
        else:
            ret[\'status\']=False
            ret[\'error\']=\'太短了\'
    except Exception as e:
        ret[\'status\']=False
        ret[\'error\']=\'请求错误\'
    return HttpResponse(json.dumps(ret))

def app(request):
    if request.method=="GET":
        app_list=models.Application.objects.all()
        host_list=models.Host.objects.all()
        #for row in app_list:
        #    print(row.name,row.r.all())
        return render(request,\'app.html\',{"app_list":app_list,"host_list":host_list})
    elif request.method=="POST":
        app_name=request.POST.get(\'app_name\')
        host_list = request.POST.getlist(\'host_list\')
        obj=models.Application.objects.create(name=app_name)
        obj.r.add(*host_list)
        return redirect(\'/app/\')

 

app.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .host-tag{
            display:inline-block;
            padding:3px;
            border:1px solid red;
            background-color:pink;
        }

        .hide{
            display:none;
        }
        .shade{
            position:fixed;
            top:0;
            bottom:0;
            right:0;
            left:0;
            background:black;
            opacity:0.6;
            z-index:100;
        }
        .add-modal,.edit-modal{
            position:fixed;
            height:300px;
            width:400px;
            top:100px;
            left:50%;
            z-index:101;
            border:1px solid red;
            background:white;
            margin-left:-200px;
        }

    </style>
</head>
<body>
    <h1>应用列表</h1>
    <div>
        <input id="add_app" type="button" value="添加"/>
    </div>
    <table border="1">
        <thead>
            <tr>
                <th>应用名称</th>
                <th>应用主机列表</th>
            </tr>
        </thead>
        <tbody>
            {% for app in app_list %}
                <tr>
                    <td>{{app.name}}</td>
                    <td>
                        {% for host in app.r.all %}
                            <span class="host-tag">{{host.hostname}}</span>
                        {% endfor %}
                    </td>
                </tr>
            {% endfor %}

        </tbody>

    </table>
    <div class="shade hide"></div>
    <div class="add-modal hide">
        <form id="add_form" method="POST" action="/app/">
            <div class="group">
                <input id="app_name" type="text" placeholder="应用名称" name="app_name"/>
            </div>

            <div class="group">
                <select id="host_list" name="host_list" multiple>
                    {% for op in host_list %}
                    <option value="{{op.nid}}">{{op.hostname}}</option>
                    {% endfor %}

                </select>
            </div>

            <input type="submit" value="提交"/>
        </form>
    </div>

    <div class="edit-modal hide">
        <form id="edit_form" method="POST" action="/host/">
            <input type="text" name="nid" style="display:none"/>
            <input type="text" placeholder="主机名" name="hostname"/>
            <input type="text" placeholder="IP" name="ip"/>
            <input type="text" placeholder="端口" name="port"/>
            <select name="b_id">
                {% for op in b_list %}
                <option value="{{op.id}}">{{op.caption}}</option>
                {% endfor %}
            </select>
            <a id="ajax_submit_edit" style="display:inline-block;padding:5px;background:blue;color:white">确认编辑</a>

        </form>
    </div>

    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        $(function(){
            $(\'#add_app\').click(function(){
                $(\'.shade,.add-modal\').removeClass(\'hide\');
            });
        $(\'#cancel\').click(function(){
            $(\'.shade,.add-modal\').addClass(\'hide\');
            });
    })
    </script>

</body>
</html>

 models.py

from django.db import models
# Create your models here.

class Business(models.Model):
    #id列,是自动创建的
    caption=models.CharField(max_length=32)
    code=models.CharField(max_length=32)

class Host(models.Model):
    nid=models.AutoField(primary_key=True)
    hostname=models.CharField(max_length=32,db_index=True) #加上索引,可以提高查询速度
    ip=models.GenericIPAddressField(protocol="ipv4",db_index=True)
    port=models.IntegerField()
    b=models.ForeignKey("Business",to_field=\'id\')


class Application(models.Model):
    name=models.CharField(max_length=32)
    r=models.ManyToManyField("Host")

#2个业务,第3张表,维护前面2张表的关系。
# class HostToApp(models.Model):
#     hobj=models.ForeignKey(to=\'Host\',to_field=\'nid\') #列名hobj_id
#     aobj=models.ForeignKey(to=\'Application\',to_field=\'id\') #列名aobj_id

 

以上是关于Day20-初识Ajax的主要内容,如果未能解决你的问题,请参考以下文章

Day15 HTML补充初识JavaScript

python初识-day2

Python初识-day1

python初识 - day4

初识ajax

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段