WEEK20:django 博客开发3
- settings.py
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', #注册类,数据库 ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 's14day20.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] STATIC_URL = '/static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), )
- models.py
from django.db import models class Business(models.Model): # 默认添加ID列 caption = models.CharField(max_length=32) code = models.CharField(max_length=32,null=True,default="SA") 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(to="Business", to_field='id') #“to=”可以省略,关联Business中的id字段 class Application(models.Model): name = models.CharField(max_length=32) r = models.ManyToManyField("Host") """ 创建多对多: 方式一:自定义关系表 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(to="Business", to_field='id') class Application(models.Model): name = models.CharField(max_length=32) class HostToApp(models.Model): hobj = models.ForeignKey(to='Host',to_field='nid') aobj = models.ForeignKey(to='Application',to_field='id') # HostToApp.objects.create(hobj_id=1,aobj_id=2) 方式二:自动创建关系表 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(to="Business", to_field='id') class Application(models.Model): name = models.CharField(max_length=32) r = models.ManyToManyField("Host") 无法直接对第三张表进行操作 obj = Application.objects.get(id=1) obj.name # 第三张表操作(间接操作) obj.r.add(1) #在表中添加关系id=1对应1 obj.r.add(2) #在表中添加关系id=1对应2 obj.r.add(2,3,4) #在表中添加关系id=1对应2,3,4 obj.r.add(*[1,2,3,4]) #增加多个关系,id=1对应1,2,3,4 obj.r.remove(1) obj.r.remove(2,4) obj.r.remove(*[1,2,3]) obj.r.clear() #清除id=1的所有对应关系 obj.r.set([3,5,7]) #更新 # 所有相关的主机对象“列表” QuerySet obj.r.all() """
- views.py
from django.shortcuts import render,HttpResponse,redirect from app01 import models import json def business(request): # 获取数据库单表数据的三种方式(获取Business数据库中的所有数据) #方法一:返回对象 v1 = models.Business.objects.all() # QuerySet # [obj(id,caption,code),obj(id,caption,code),obj(id,caption,code) ] # 方法二:返回字典 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) # # QuerySet [hostobj(ip.host,����һ������(..)),] # # 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') # # print(row.b.fk.name) # # return HttpResponse("Host") # v2 = models.Host.objects.filter(nid__gt=0).values('nid','hostname','b_id','b__caption') # # QuerySet: [ {} ] # # print(v2) # # 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') # # QuerySet: [ {} ] # # print(v2) # 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) #获取id字段时使用一个下划线_,其他字段需要使用双下划綫__.原因如下: #id 字段是自动添加的,对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名 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=models.Business.objects.get(id=b) # ) models.Host.objects.create(hostname=h, ip=i, port=p, b_id=b #b为对象 ) return redirect('/host') #不能使用render进行重新渲染,否则无法获取之前的数据。使用redirect的get方法重新访问网页。 def test_ajax(request): 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() # for row in app_list: # print(row.name,row.r.all()) host_list = models.Host.objects.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') # print(app_name,host_list) obj = models.Application.objects.create(name=app_name) obj.r.add(*host_list) return redirect('/app') def ajax_add_app(request): ret = {'status':True, 'error':None, 'data': None} 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 HttpResponse(json.dumps(ret))
- apps.py
from django.apps import AppConfig class App01Config(AppConfig): name = 'app01'
- 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), #添加终止符$,防止business和business_add同时存在的时候,无法匹配访问business_add url(r'^host/$', views.host), url(r'^test_ajax/$', views.test_ajax), url(r'^app/$', views.app), url(r'^ajax_add_app/$', views.ajax_add_app), # url(r'^business_add', views.business), ]
- host.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .hide{ display: none; } .shade{ position: fixed; top: 0; right: 0; left: 0; bottom: 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_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 }}"> <!--forloop.counter来替代row.nid,用来显示索引:序号。 counter从1开始,counter0从0开始,revcounter倒叙排列到1,revcounter0倒叙排列到0,last是否为最后一个,first是否为第一个, parentloop在嵌套循环时的父循环的前面6个值为多少--> <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>主机列表(字典)</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>主机列表(元组)</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 id="add_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="提交" /> <input id="cancel" type="button" value="取消" /> <a id="ajax_submit" >悄悄提交</a> <span id="erro_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" >确认编辑</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()}, data: $('#add_form').serialize(), success: function(data){ var obj = JSON.parse(data); //反序列化,将获取到的数据字符串转换成对象。stringify为序列化 if(obj.status){ location.reload(); //刷新页面 }else{ $('#erro_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>
- business.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <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.id }} - {{ row.caption }}</li> {% endfor %} </ul> <h1>业务线列表(元组)</h1> <ul> {% for row in v3 %} <li>{{ row.0 }} - {{ row.1 }}</li> {% endfor %} </ul> </body> </html>
- app.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> .host-tag{ display: inline-block; padding: 3px; border: 1px solid red; background-color: palevioletred; } .hide{ display: none; } .shade{ position: fixed; top: 0; right: 0; left: 0; bottom: 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> <td>应用名称</td> <td>应用主机列表</td> </tr> </thead> <tbody> {% for app in app_list %} <tr aid="{{ app.id }}"> <td>{{ app.name }}</td> <td> {% for host in app.r.all %} <span class="host-tag" hid="{{ host.nid }}"> {{ host.hostname }} </span> {% endfor %} </td> <td> <a class="edit">编辑</a> </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="提交" /> <input id="add_submit_ajax" type="button" value="Ajax提交" /> </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="app" /> <select name="host_list" multiple> {% for op in host_list %} <option value="{{ op.nid }}">{{ op.hostname }}</option> {% endfor %} </select> <a id="ajax_submit_edit" >确认编辑</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'); }); $('#add_submit_ajax').click(function(){ $.ajax({ url: '/ajax_add_app', // data: {'user': 123,'host_list': [1,2,3,4]}, data: $('#add_form').serialize(), type: "POST", dataType: 'JSON', // 内部自行处理,JSON.parse(data) traditional: true, //能够传输列表,不加只能传输字符串和数字 success: function(obj){ console.log(obj); }, error: function () { } }) }); $('.edit').click(function(){ $('.edit-modal,.shade').removeClass('hide'); var hid_list = []; $(this).parent().prev().children().each(function(){ var hid = $(this).attr('hid'); hid_list.push(hid) }); $('#edit_form').find('select').val(hid_list); // 如果发送到后台 // /* obj = models.Application.objects.get(id=ai) obj.name = "新Name" obj.save() obj.r.set([1,2,3,4]) */ }) }) </script> </body> </html>
仰天大笑出门去,吾辈岂是蓬蒿人!