Django入门(二)之一对多和多对多表结构操作、Ajax提交

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Dream_ya/article/details/86562568

上一篇文章>Django入门(一)之视图、路由系统URL、ORM操作

一、本机环境


操作系统:Red Hat Enterprise Linux Server release 7.3 (Maipo)
python版本:python3.6
[root@python _Django]# tree project
project
├── app
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   ├── __init__.py
│   │   └── __pycache__
│   │       ├── 0001_initial.cpython-36.pyc
│   │       ├── 0002_business_code.cpython-36.pyc
│   │       └── __init__.cpython-36.pyc
│   ├── models.py
│   ├── __pycache__
│   │   ├── admin.cpython-36.pyc
│   │   ├── __init__.cpython-36.pyc
│   │   ├── models.cpython-36.pyc
│   │   └── views.cpython-36.pyc
│   ├── tests.py
│   └── views.py
├── db.sqlite3
├── manage.py
├── project
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   ├── settings.cpython-36.pyc
│   │   ├── urls.cpython-36.pyc
│   │   └── wsgi.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── static
│   └── jquery-1.12.4.min.js
└── templates

二、获取单表数据的三种方式


三种方式:对象方式、字典方式、元组方式

1、配置urls.py

[root@python project]# ls
app  db.sqlite3  manage.py  project  static  templates

[root@python project]# vim project/urls.py
from django.contrib import admin
from django.urls import path
from app import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('business/', views.business),
]

2、配置models.py

 ###创建数据库表,可以在settings.py中进行其他数据库的连接(默认sqlite)
[root@python project]# vim app/models.py
from django.db import models

class Business(models.Model):
    caption = models.CharField(max_length=32)
    code = models.CharField(max_length=10, null=True, default='DM')

class Host(models.Model):
    nid = models.AutoField(primary_key=True)
    ### db_index加索引
    hostname = models.CharField(max_length=32, db_index=True)
    ip = models.GenericIPAddressField(protocol='ipv4', db_index=True)
    port = models.IntegerField()
    b = models.ForeignKey(to='Business', to_field='id', on_delete=models.CASCADE)

3、配置views.py

[root@python project]# vim app/views.py
from django.shortcuts import render
from app import models

def business(request):
    ### QuerySet,对象方式
    v = models.Business.objects.all()
    ### QuerySet,字典方式
    v1 = models.Business.objects.all().values('id', 'caption', 'code')
    ### QuerySet,元组方式
    v2 = models.Business.objects.all().values_list('id', 'caption', 'code')
    return render(request, 'business.html', {'v': v, 'v1': v1, 'v2': v2})

4、配置business.html

[root@python project]# vim templates/business.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>部门(对象)</h1>
    <ul>
        {% for row in v %}
        <li>{{ row.id }}-{{ row.caption }}-{{ row.code }}</li>
        {% endfor %}
    </ul>
    <h1>部门(字典)</h1>
    <ul>
        {% for row in v1 %}
        <li>{{ row.id }}-{{ row.caption }}-{{ row.code }}</li>
        {% endfor %}
    </ul>
    <h1>部门(元组)</h1>
    <ul>
        {% for row in v2 %}
        <li>{{ row.0 }}-{{ row.1 }}-{{ row.2 }}</li>
        {% endfor %}
    </ul>
</body>
</html>

5、启动并访问

浏览器访问:http://10.10.10.111:8000/business/

[root@python project]# python manage.py makemigrations
[root@python project]# python manage.py migrate
### 数据库中插入数据
[root@python project]# mysql -uroot -p1
MariaDB [(none)]> select * from project.app_business;
+----+-----------------+------+
| id | caption         | code |
+----+-----------------+------+
|  1 | 技术支持部      | DM   |
|  2 | 研发部          | DM   |
|  3 | 销售部          | DM   |
|  4 | 测试部          | DM   |
+----+-----------------+------+

[root@python project]# python manage.py runserver 10.10.10.111:8000

三、一对多跨表操作


1、数据库添加数据

[root@python project]# mysql -uroot -p1
MariaDB [(none)]> select * from project.app_host;    
+-----+----------+------------+-------+------+
| nid | hostname | ip         | port  | b_id |
+-----+----------+------------+-------+------+
|   1 | server1  | 10.10.10.1 | 10001 |    1 |
|   2 | server2  | 10.10.10.2 | 10002 |    2 |
|   3 | server3  | 10.10.10.3 | 10003 |    2 |
+-----+----------+------------+-------+------+

2、配置urls.py

[root@python project]# vim project/urls.py
from django.contrib import admin
from django.urls import path
from django.urls import re_path
from app import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('business/', views.business),
    re_path('host$', views.host),
]

3、配置views.py

[root@python project]# vim app/views.py
from django.shortcuts import render
from django.shortcuts import HttpResponse
from app import models

def business(request):
    ### QuerySet,对象方式
    v = models.Business.objects.all()
    ### QuerySet,字典方式
    v1 = models.Business.objects.all().values('id', 'caption', 'code')
    ### QuerySet,元组方式
    v2 = models.Business.objects.all().values_list('id', 'caption', 'code')
    return render(request, 'business.html', {'v': v, 'v1': v1, 'v2': v2})

def host(request):
    v1 = models.Host.objects.filter(nid__gt=0)
    for row in v1:
        ### sep:间隔为table
        print (row.nid, row.hostname, row.ip, row.port, row.b_id, row.b.caption, row.b.code, row.b.id, sep='\t')
    return HttpResponse('host ok')

4、访问

http://10.10.10.111:8000/host
[root@python project]# python manage.py runserver 10.10.10.111:8000
...
1       server1 10.10.10.1      10001   1       技术支持部      DM      1
2       server2 10.10.10.2      10002   2       研发部  DM      2
3       server3 10.10.10.3      10003   2       研发部  DM      2

四、三种模式


1、修改views.py

[root@python project]# vim app/views.py
def host(request):
    v1 = models.Host.objects.filter(nid__gt=0)
    for row in v1:
        print (row.nid, row.hostname, row.ip, row.port, row.b_id, row.b.caption, row.b.code, row.b.id, sep='\t')
    # return HttpResponse('host ok')
    v2 = models.Host.objects.filter(nid__gt=0).values('nid', 'hostname','b_id', 'b__caption')
    for row2 in v2:
        print (row2)
        # print (row2['nid'], row2['hostname'], row2['b_id'],row2['b__caption'])
    v3 = models.Host.objects.filter(nid__gt=0).values_list('nid', 'hostname','b_id', 'b__caption')
    for row3 in v3:
        print (row3)
    return render(request, 'host.html', {'v1': v1, 'v2': v2, 'v3': v3,})

2、配置html

[root@python project]# vim templates/host.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Info(对象):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>IP</th>
            <th>端口</th>
            <th>部门名称</th>
            <th>部门编码</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v1 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ row.b_id }}">
                <td>{{ row.hostname }}</td>
                <td>{{ row.ip }}</td>
                <td>{{ row.port }}</td>
                <td>{{ row.b.caption }}</td>
                <td>{{ row.b.code }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

<h1>Info(字典):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v2 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ row.b_id }}">
                <td>{{ row.hostname }}</td>
                <td>{{ row.b__caption }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

<h1>Info(元组):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v3 %}
            <!--隐藏id-->
            <tr host-id="{{ row.0 }}" b-id="{{ row.2 }}">
                <td>{{ row.1 }}</td>
                <td>{{ row.3 }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>
</body>
</html>

五、排序


1、说明

正序:forloop.counter、forloop.counter0
倒序:forloop.revcounter、forloop.revcounter0
是否为第一个(布尔):forloop.first
是否为最后一个(布尔):forloop.last

2、配置host.html

[root@python project]# vim templates/host.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Info(对象):</h1>
<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 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ 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>{{ row.b.code }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

<h1>Info(字典):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v2 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ row.b_id }}">
                <td>{{ row.hostname }}</td>
                <td>{{ row.b__caption }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

<h1>Info(元组):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v3 %}
            <!--隐藏id-->
            <tr host-id="{{ row.0 }}" b-id="{{ row.2 }}">
                <td>{{ row.1 }}</td>
                <td>{{ row.3 }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>
</body>
</html>

3、forloop.parentloop

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Info(对象):</h1>
<table border="1">
    <thead>
        <tr>
            <th>序号</th>
            <th>主机名</th>
            <th>IP</th>
            <th>端口</th>
            <th>部门名称</th>
            <th>部门编码</th>
        </tr>
    </thead>
    <tbody>
    {% for i in v1 %}
        {% for row in v1 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ row.b_id }}">
                <td>{{ forloop.parentloop }}</td>
                <td>{{ row.hostname }}</td>
                <td>{{ row.ip }}</td>
                <td>{{ row.port }}</td>
                <td>{{ row.b.caption }}</td>
                <td>{{ row.b.code }}</td>
            </tr>
        {% endfor %}
    {% endfor %}
    </tbody>
</table>

<h1>Info(字典):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v2 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ row.b_id }}">
                <td>{{ row.hostname }}</td>
                <td>{{ row.b__caption }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

<h1>Info(元组):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v3 %}
            <!--隐藏id-->
            <tr host-id="{{ row.0 }}" b-id="{{ row.2 }}">
                <td>{{ row.1 }}</td>
                <td>{{ row.3 }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>
</body>
</html>

4、添加数据

(1)配置views.py
[root@python project]# vim app/views.py
from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from app import models

def business(request):
    ### QuerySet,对象方式
    v = models.Business.objects.all()
    ### QuerySet,字典方式
    v1 = models.Business.objects.all().values('id', 'caption', 'code')
    ### QuerySet,元组方式
    v2 = models.Business.objects.all().values_list('id', 'caption', 'code')
    return render(request, 'business.html', {'v': v, 'v1': v1, 'v2': v2})


def host(request):
    if request.method == 'GET':
        v1 = models.Host.objects.filter(nid__gt=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')
(2)配置host.html
[root@python project]# vim templates/host.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .hide{
            display: none;
        }
        .shade{
            position: fixed;
            top: 0;
            right: 0;
            left: 0;
            bottom: 0;
            background: #b9def0;
            opacity: 0.6;
            z-index: 100;
        }
        .add-model{
            position: fixed;
            height: 300px;
            width: 600px;
            top: 100px;
            left: 50%;
            border: 2px solid burlywood;
            z-index: 101;
            margin-left: -300px;
            background-color: #b9def0;
        }
    </style>
</head>
<body>
<h1>Info(对象):</h1>
<div>
    <input id="add-element"  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 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ 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>Info(字典):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v2 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ row.b_id }}">
                <td>{{ row.hostname }}</td>
                <td>{{ row.b__caption }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

<h1>Info(元组):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v3 %}
            <!--隐藏id-->
            <tr host-id="{{ row.0 }}" b-id="{{ row.2 }}">
                <td>{{ row.1 }}</td>
                <td>{{ row.3 }}</td>
            </tr>
        {% endfor %}
    </tbody>
    <div class="shade hide"></div>
    <div class="add-model hide">
        <form action="/host" method="POST">
            <div class="group">
                <input type="text" placeholder="主机名" name="hostname">
            </div>
            <div class="group">
                <input type="text" placeholder="IP" name="ip">
            </div>
            <div class="group">
                <input type="text" placeholder="端口" name="port">
            </div>
            <div class="group">
                <select name="b_id">
                    {% for i in b_list %}
                    <option value="{{ i.id }}">{{ i.caption }}</option>
                    {% endfor %}
                </select>
            </div>
                <input type="submit" value="提交" />
                <input id="cancel" type="button" value="取消" />
        </form>
    </div>

    <script src="/static/jquery-1.12.4.min.js"></script>
    <script>
        $(function () {
            $('#add-element').click(function () {
                $('.shade,.add-model').removeClass('hide');
            })
            $('#cancel').click(function () {
                $('.shade,.add-model').addClass('hide');
            })
        })
    </script>
</table>
</body>
</html>

六、Ajax提交


1、介绍

Ajax:
简单写法:
	$.ajax({
		url: '/host',
		type: "POST",
		data: {'key': value,'key2': "value2"},
		success: function(data){
			// data是服务器端返回的字符串
			var obj = JSON.parse(data);
		}
	})
	
通用写法:
	$.ajax({
	url: '/index/',
	data: {'k': 'v', 'list': [1,2,3,4], 'k3': JSON.stringfy({'k1': 'v'}))}, $(form对象).serilize() 
	type: 'POST',
	dataType: 'JSON':
	traditional: true,
	success:function(d){
		location.reload()              # 刷新
		location.href = "某个地址"     # 跳转
	}
	})
		
### 建议让服务器端返回一个字典
return HttpResponse(json.dumps(字典))

2、通过Ajax提交

(1)配置urls.py
[root@python project]# vim project/urls.py
from django.contrib import admin
from django.urls import path
from django.urls import re_path
from app import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('business/', views.business),
    re_path('host$', views.host),
    path('test_ajax/', views.test_ajax),
]
(2)配置views.py
[root@python project]# vim app/views.py
from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from app import models

def business(request):
    ### QuerySet,对象方式
    v = models.Business.objects.all()
    ### QuerySet,字典方式
    v1 = models.Business.objects.all().values('id', 'caption', 'code')
    ### QuerySet,元组方式
    v2 = models.Business.objects.all().values_list('id', 'caption', 'code')
    return render(request, 'business.html', {'v': v, 'v1': v1, 'v2': v2})

def host(request):
    if request.method == 'GET':
        v1 = models.Host.objects.filter(nid__gt=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) > 3:
        models.Host.objects.create(
            hostname=h,
            ip=i,
            port=p,
            b_id=b,
        )
        return HttpResponse('OK')
    else:
        return HttpResponse('Hostname is to short!!!')
(3)配置HTML
[root@python project]# vim templates/host.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .hide{
            display: none;
        }
        .shade{
            position: fixed;
            top: 0;
            right: 0;
            left: 0;
            bottom: 0;
            background: #b9def0;
            opacity: 0.6;
            z-index: 100;
        }
        .add-model{
            position: fixed;
            height: 300px;
            width: 600px;
            top: 100px;
            left: 50%;
            border: 2px solid burlywood;
            z-index: 101;
            margin-left: -300px;
            background-color: #b9def0;
        }
    </style>
</head>
<body>
<h1>Info(对象):</h1>
<div>
    <input id="add-element"  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 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ 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>Info(字典):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v2 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ row.b_id }}">
                <td>{{ row.hostname }}</td>
                <td>{{ row.b__caption }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

<h1>Info(元组):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v3 %}
            <!--隐藏id-->
            <tr host-id="{{ row.0 }}" b-id="{{ row.2 }}">
                <td>{{ row.1 }}</td>
                <td>{{ row.3 }}</td>
            </tr>
        {% endfor %}
    </tbody>
    <div class="shade hide"></div>
    <div class="add-model hide">
        <form action="/host" method="POST">
            <div class="group">
                <input id="hostname" 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 i in b_list %}
                    <option value="{{ i.id }}">{{ i.caption }}</option>
                    {% endfor %}
                </select>
            </div>
                <input type="submit" value="提交" />
                <input id='ajax-submit' type="button" value="ajax提交"/>
                <input id="cancel" type="button" value="取消" />
        </form>
    </div>
    <script src="/static/jquery-1.12.4.min.js"></script>
    <script>
        $(function () {
            $('#add-element').click(function () {
                $('.shade,.add-model').removeClass('hide');
            });
            $('#cancel').click(function () {
                $('.shade,.add-model').addClass('hide');
            });
            $('#ajax-submit').click(function () {
                $.ajax({
                    url: "/test_ajax/",
                    type: 'POST',
                    data: {'hostname': $('#hostname').val(), 'ip': $('#ip').val(),'port':  $('#hostname').val(), 'b_id': $('#sel').val(),},
                    success: function (data) {
                        if(data == 'OK'){
                            location.reload();
                        }else {
                            alert(data);
                        }
                    }
                })
            });
        })
    </script>
</table>
</body>
</html>

3、优化

(1)配置views.py
[root@python project]# vim app/views.py
from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from app import models

def business(request):
    ### QuerySet,对象方式
    v = models.Business.objects.all()
    ### QuerySet,字典方式
    v1 = models.Business.objects.all().values('id', 'caption', 'code')
    ### QuerySet,元组方式
    v2 = models.Business.objects.all().values_list('id', 'caption', 'code')
    return render(request, 'business.html', {'v': v, 'v1': v1, 'v2': v2})

def host(request):
    if request.method == 'GET':
        v1 = models.Host.objects.filter(nid__gt=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
    res = {'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) > 3:
            models.Host.objects.create(
                hostname=h,
                ip=i,
                port=p,
                b_id=b,
            )
        else:
            res['status'] = False
            res['error'] = 'Hostname is to short!!!'
    except Exception as e:
        res['status'] = False
        res['error'] = '请求错误!!!'
    return HttpResponse(json.dumps(res))
(2)配置HTML
[root@python project]# vim templates/host.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .hide{
            display: none;
        }
        .shade{
            position: fixed;
            top: 0;
            right: 0;
            left: 0;
            bottom: 0;
            background: #b9def0;
            opacity: 0.6;
            z-index: 100;
        }
        .add-model{
            position: fixed;
            height: 300px;
            width: 600px;
            top: 100px;
            left: 50%;
            border: 2px solid burlywood;
            z-index: 101;
            margin-left: -300px;
            background-color: #b9def0;
        }
    </style>
</head>
<body>
<h1>Info(对象):</h1>
<div>
    <input id="add-element"  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 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ 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>Info(字典):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v2 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ row.b_id }}">
                <td>{{ row.hostname }}</td>
                <td>{{ row.b__caption }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

<h1>Info(元组):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v3 %}
            <!--隐藏id-->
            <tr host-id="{{ row.0 }}" b-id="{{ row.2 }}">
                <td>{{ row.1 }}</td>
                <td>{{ row.3 }}</td>
            </tr>
        {% endfor %}
    </tbody>
    <div class="shade hide"></div>
    <div class="add-model hide">
        <form action="/host" method="POST">
            <div class="group">
                <input id="hostname" 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 i in b_list %}
                    <option value="{{ i.id }}">{{ i.caption }}</option>
                    {% endfor %}
                </select>
            </div>
                <input type="submit" value="提交" />
                <input id='ajax-submit' type="button" value="ajax提交"/>
                <input id="cancel" type="button" value="取消" />
                <span id="error-msg" style="color: red;"></span>
        </form>
    </div>
    <script src="/static/jquery-1.12.4.min.js"></script>
    <script>
        $(function () {
            $('#add-element').click(function () {
                $('.shade,.add-model').removeClass('hide');
            });
            $('#cancel').click(function () {
                $('.shade,.add-model').addClass('hide');
            });
            $('#ajax-submit').click(function () {
                $.ajax({
                    url: "/test_ajax/",
                    type: 'POST',
                    data: {'hostname': $('#hostname').val(), 'ip': $('#ip').val(),'port':  $('#hostname').val(), 'b_id': $('#sel').val(),},
                    success: function (data) {
                        //JSON.stringify:可以实现序列化
                        var obj = JSON.parse(data);
                        if(obj.status){
                            location.reload();
                        }else {
                            $('#error-msg').text(obj.error);
                        }
                    }
                })
            });
        })
    </script>
</table>
</body>
</html>

4、Ajax编辑(serialize)

(1)配置urls.py
[root@python project]# vim project/urls.py
from django.contrib import admin
from django.urls import path
from django.urls import re_path
from app import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('business/', views.business),
    re_path('host$', views.host),
    path('test_ajax/', views.test_ajax),
    path('edit_ajax/', views.edit_ajax),
]
(2)配置views.py
[root@python project]# vim app/views.py
from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect
from app import models

def business(request):
    ### QuerySet,对象方式
    v = models.Business.objects.all()
    ### QuerySet,字典方式
    v1 = models.Business.objects.all().values('id', 'caption', 'code')
    ### QuerySet,元组方式
    v2 = models.Business.objects.all().values_list('id', 'caption', 'code')
    return render(request, 'business.html', {'v': v, 'v1': v1, 'v2': v2})


def host(request):
    if request.method == 'GET':
        v1 = models.Host.objects.filter(nid__gt=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
    res = {'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) > 3:
            models.Host.objects.create(
                hostname=h,
                ip=i,
                port=p,
                b_id=b,
            )
        else:
            res['status'] = False
            res['error'] = 'Hostname is to short!!!'
    except Exception as e:
        res['status'] = False
        res['error'] = '请求错误!!!'
    return HttpResponse(json.dumps(res))

def edit_ajax(request):
    # a = request.POST.getall()
    nid = request.POST.get('nid')
    h = request.POST.get('hostname')
    i = request.POST.get('ip')
    p = request.POST.get('port')
    models.Host.objects.filter(nid=nid).update(
        hostname = h,
        ip=i,
        port=p,
    )
    return HttpResponse('OK')
(3)配置HTML
[root@python project]# vim templates/host.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .hide{
            display: none;
        }
        .shade{
            position: fixed;
            top: 0;
            right: 0;
            left: 0;
            bottom: 0;
            background: #b9def0;
            opacity: 0.6;
            z-index: 100;
        }
        .add-model,.edit-model{
            position: fixed;
            height: 300px;
            width: 600px;
            top: 100px;
            left: 50%;
            border: 2px solid burlywood;
            z-index: 101;
            margin-left: -300px;
            background-color: #b9def0;
        }
    </style>
</head>
<body>
<h1>Info(对象):</h1>
<div>
    <input id="add-element"  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 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ 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>Info(字典):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v2 %}
            <!--隐藏id-->
            <tr host-id="{{ row.nid }}" b-id="{{ row.b_id }}">
                <td>{{ row.hostname }}</td>
                <td>{{ row.b__caption }}</td>
            </tr>
        {% endfor %}
    </tbody>
</table>

<h1>Info(元组):</h1>
<table border="1">
    <thead>
        <tr>
            <th>主机名</th>
            <th>部门名称</th>
        </tr>
    </thead>
    <tbody>
        {% for row in v3 %}
            <!--隐藏id-->
            <tr host-id="{{ row.0 }}" b-id="{{ row.2 }}">
                <td>{{ row.1 }}</td>
                <td>{{ row.3 }}</td>
            </tr>
        {% endfor %}
    </tbody>
    <div class="shade hide"></div>
    <div class="add-model hide">
        <form action="/host" method="POST">
            <div class="group">
                <input id="hostname" 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 i in b_list %}
                    <option value="{{ i.id }}">{{ i.caption }}</option>
                    {% endfor %}
                </select>
            </div>
                <input type="submit" value="提交" />
                <input id='ajax-submit' type="button" value="ajax提交"/>
                <input id="cancel" type="button" value="取消" />
                <span id="error-msg" style="color: red;"></span>
        </form>
    </div>
    <div class="edit-model hide">
        <form id="edit-form" action="/host" method="POST">
                <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 i in b_list %}
                    <option value="{{ i.id }}">{{ i.caption }}</option>
                    {% endfor %}
                </select>
                <!--<input type="submit" value="提交" />-->
                <input id='ajax-submit-edit' type="button" value="确定编辑"/>
        </form>
    </div>
    <script src="/static/jquery-1.12.4.min.js"></script>
    <script>
        $(function () {
            $('#add-element').click(function () {
                $('.shade,.add-model').removeClass('hide');
            });
            $('#cancel').click(function () {
                $('.shade,.add-model').addClass('hide');
            });
            $('#ajax-submit').click(function () {
                $.ajax({
                    url: "/edit_ajax/",
                    type: 'POST',
                    data: {'hostname': $('#hostname').val(), 'ip': $('#ip').val(),'port':  $('#hostname').val(), 'b_id': $('#sel').val(),},
                    success: function (data) {
                        //JSON.stringify:可以实现序列化
                        var obj = JSON.parse(data);
                        if(obj.status){
                            location.reload();
                        }else {
                            $('#error-msg').text(obj.error);
                        }
                    }
                })
            });
            $('.edit').click(function () {
                $('.shade,.edit-model').removeClass('hide');
                var bid = $(this).parent().parent().attr('b-id');
                var nid = $(this).parent().parent().attr('host-id');
                $('#edit-form').siblings('select').val(bid);
                $('#edit-form').siblings('input[name="nid"]').val(nid);
            });
            //修改
            $('#ajax-submit-edit').click(function () {
                $.ajax({
                    url: "/edit_ajax/",
                    type: 'POST',
                    data: $('#edit-form').serialize(),
                    success: function (data1) {
                        location.reload();
                    }
                })
            })
        })
    </script>
</table>
</body>
</html>

七、多对多操作


1、多对多创建

执行这二条命令创建:python manage.py makemigrations;python manage.py migrate

(1)方式一、自定义关系表
[root@python project]# vim app/models.py     ###两个表通过HostToApp实现关联
class Host(models.Model):
    nid = models.AutoField(primary_key=True)
    ### db_index加索引
    hostname = models.CharField(max_length=32, db_index=True)
    ip = models.GenericIPAddressField(protocol='ipv4', db_index=True)
    port = models.IntegerField()
    b = models.ForeignKey(to='Business', to_field='id', on_delete=models.CASCADE)

class Application(models.Model):
    name = models.CharField(max_length=32)

class HostToApp(models.Model):
    hobj = models.ForeignKey(to='Host', to_field='nid', on_delete=models.CASCADE)
    aobj = models.ForeignKey(to='Application', on_delete=models.CASCADE)
(2)方式二、自动创建关系表
### 可以发现会自动新建表app_application_r(相当于我们上面的HostToApp),最多生成3列
### 无法直接对第三张表进行操作
[root@python project]# vim app/models.py  
class Host(models.Model):
    nid = models.AutoField(primary_key=True)
    ### db_index加索引
    hostname = models.CharField(max_length=32, db_index=True)
    ip = models.GenericIPAddressField(protocol='ipv4', db_index=True)
    port = models.IntegerField()
    b = models.ForeignKey(to='Business', to_field='id', on_delete=models.CASCADE)

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

2、实例

这里我们使用方式二!!!

(1)配置urls.py
[root@python project]# vim project/urls.py
from django.contrib import admin
from django.urls import path
from django.urls import re_path
from app import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('business/', views.business),
    re_path('host$', views.host),
    path('test_ajax/', views.test_ajax),
    path('edit_ajax/', views.edit_ajax),
    path('app/', views.app),
]
(2)配置HTML
[root@python project]# vim templates/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 blanchedalmond;
            background-color: #b9def0;
        }
    </style>
</head>
<body>
    <h1>应用列表</h1>
    <table border="1px">
        <thead>
            <tr>
                <td>应用名称</td>
                <td>应用主机列表</td>
            </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>
</body>
</html>
[root@python project]# python manage.py makemigrations
[root@python project]# python manage.py migrate
(3)生成的数据库表自行设置
MariaDB [(none)]> select * from project.app_application;
+----+-------+
| id | name  |
+----+-------+
|  1 | cache |
|  2 | proxy |
|  3 | web   |
+----+-------+
MariaDB [(none)]> select * from project.app_application_r;
+----+----------------+---------+
| id | application_id | host_id |
+----+----------------+---------+
|  1 |              1 |       1 |
|  5 |              1 |       4 |
|  2 |              2 |       3 |
|  3 |              3 |       1 |
+----+----------------+---------+
(4)运行访问
[root@python project]#  python manage.py runserver 10.10.10.111:8000
http://10.10.10.111:8000/app/            ###通过浏览器访问

下一篇文章>Django补充(三)之路由系统URL、自定义函数、自定义分页、Cookie操作、FBV和CBV

猜你喜欢

转载自blog.csdn.net/Dream_ya/article/details/86562568
今日推荐