路由系統 -> 視圖函數(獲取模板+數據 -> 渲染) -> 字符串返回給用戶html
/index/ #-> 函數或類.as_view() /detail/(\d+) #-> 函數(參數) 或 類.as_view()(參數) /detail/(?P<nid>\d+) #-> 函數(參數) 或 類.as_view()(參數) /detail/ #-> include("app01.urls") /detail/ name='a1' #-> include("app01.urls") #-> 視圖中:reverse #-> 模板中:{% url "a1" %}
FBV:函數前端
def index(request,*args,**kwargs):
CBV:類python
class Home(views.View): def get(self,reqeust,*args,**kwargs):
獲取用戶請求中的數據:mysql
request.POST.get request.GET.get reqeust.FILES.get() # checkbox,select ........getlist()
文件對象jquery
文件對象 = reqeust.FILES.get() 文件對象.name 文件對象.size 文件對象.chunks() # 直接循環文件對象也能夠 # 特殊的設置 <form action="/login/" method="POST" enctype="multipart/form-data">
給用戶返回數據:ajax
render(request, "模板文件路徑", {'k1': [1,2,3,4],"k2": {'name': 'lgeng','age': 73}}) redirect("URL") HttpResponse('字符串')
render(request, "模板路徑", {'obj': 1234, 'k1': [1,2,3,4],"k2": {'name': 'lgeng','age': 22}})
<html> <body> <h1> {{ obj }} </h1> # 取變量值 <h1> {{ k1.3 }} </h1> # 取列表的值 <h1> {{ k2.name }} </h1> # 取字典的值 {% for i in k1 %} # 循環列表的值 <p> {{ i }} </p> # 取值 {% endfor %}{% for row in k2.keys %} # 循環取字典key {{ row }} # 取值 {% endfor %}{% for row in k2.values %} # 循環取字典values {{ row }} # 取值 {% endfor %}{% for k,v in k2.items %} # 循環取key、values {{ k }} - {{v}} # 取值 {% endfor %} # 注意:模板語言循環keys、values、items這裏不加 "()" </body> </html>
class User(models.Model): age = models.IntergerFiled() # 整數在後面加長度不起做用 name = models.CharField(max_length=10) # 字符長度 # 生成數據庫結構命令 Python manage.py makemigrations python manage.py migrate # settings.py 配置 註冊APP
# 增 models.User.objects.create(name='qianxiaohu',age=18) # 第一種 dic = {'name': 'xx', 'age': 19} # 第二種 models.User.objects.create(**dic) # **dic obj = models.User(name='xiao',age=18) # 第三種 obj.save() # 刪 models.User.objects.filter(id=1).delete() # 改 models.User.objects.filter(id__gt=1).update(name='alex',age=84) dic = {'name': 'xx', 'age': 19} models.User.objects.filter(id__gt=1).update(**dic) # 查 models.User.objects.filter(id=1,name='root') models.User.objects.filter(id__gt=1,name='root')# 大於 models.User.objects.filter(id__lt=1) # 小於 models.User.objects.filter(id__gte=1) # 大於等於 models.User.objects.filter(id__lte=1) # 小於等於 models.User.objects.filter(id=1,name='root') dic = {'name': 'xx', 'age__gt': 19} models.User.objects.filter(**dic) # 這裏也能夠傳字典,增刪改查均可以加字典
class Business(models.Model): # id caption = models.CharField(max_length=32) code = models.CharField(max_length=32,null=True,default="SA") # 新增列 容許爲空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') # 表中生成列名:b_id # b = models.ForeignKey("Business", to_field='id') # 外鍵約束, # b = models.ForeignKey("Business") #只寫表名,默認與那張表主鍵關聯 # 外鍵: # v = models.Host.objects.filter(nid__gt=0) # v[0].b.caption #----> 經過.進行跨表
v1 = models.Business.objects.all() #QuerySet類型 ,內部元素都是對象(對象內相似字典結構) v2 = models.Business.objects.all().values('id','caption') #QuerySet ,內部元素都是字典 v3 = models.Business.objects.all().values_list('id','caption') #QuerySet ,內部元素都是元組 #=============== models.Business.objects.get(id=1) #獲取到的一個對象,若是不存在就報錯 obj = models.Business.objects.filter(id=1).first() #對象或者None
urls.pysql
from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^business$', views.business), ]
views.py數據庫
from django.shortcuts import render, redirect, HttpResponse from app01 import models def business(request): v1 = models.Business.objects.all() # QuerySet # [obj(id,caption,code), obj(id,caption,code), obj(id,caption,code)] v2 = models.Business.objects.values('id','caption') # QuerySet # [{'id':1,'caption':'運維'},{'id':1,'caption':'運維'},{'id':1,'caption':'運維'}] v3 = models.Business.objects.values_list('id','caption') # QuerySet # [(1,運維),(2,開發)] return render(request, "business.html", {'v1':v1,'v2':v2 ,'v3':v3})
business.htmldjango
<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>
必定要注意:「.」和「__」跨表,在不一樣場景的應用。json
點跨表,點的是對象,雙下劃線,是在filter裏的字符串中。
具體用法看示例,及註釋
urls.py
url(r'^host$', views.host),
views.py
def host(request): v1 = models.Host.objects.filter(nid__gt=0) # 同 all() # QuerySet [host 對象,] for row in v1: print(row.nid,row.b_id,row.b.caption,sep='\t') # 注意 row.b.caption 的含義 # 注意:這裏經過"__"雙下劃線跨表。'b__caption' 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']) # 注意:這裏經過"__"雙下劃線跨表。'b__caption' v3= models.Host.objects.filter(nid__gt=0).values_list('nid','hostname','b_id','b__caption') # QuerySet: [ () ] b_list = models.Business.objects.all() return render(request, 'host.html', {'v1':v1, 'v2':v2, 'v3':v3, 'b_list':b_list})
host.html
<body> <h1>主機列表(對象)</h1> <table border="1"> <thead> <tr> <th>主機名</th> <th>IP</th> <th>端口</th> <th>業務線名稱</th> </tr> </thead> <tbody> {% for row in v1 %} <tr hid="{{ row.nid }}" bid="{{ row.b.id }}"> {# 主機id不須要讓用戶看見,但修改時又須要,因此自定義個屬性#} <td>{{ row.hostname }}</td> <td>{{ row.ip }}</td> <td>{{ row.port }}</td> <td>{{ row.b.caption }}</td> </tr> {% endfor %} </tbody> </table> <hr> <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> <hr> <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> </body>
若是前端展現序號的話,模板語言for循環那裏有幾個點能夠實現。
{% for row in v1 %} # 假設3條數據 {{ forloop.counter}} # 依次爲:一、二、3 {{ forloop.counter0}} # 依次爲:0、一、2 {{ forloop.revcounter}} # 依次爲:三、二、1 {{ forloop.revcounter0}} # 依次爲:二、一、0 {{ forloop.last }} # 是否最後一個,是爲True,其餘False {{ forloop.first }} # 是否第一個 {{ forloop.parentloop }} # 嵌套循環,表示上層循環的上面的六個值分別是多少。 {% endfor %}
CSS 知識點position回顧:
fixed
:生成絕對定位的元素,相對於瀏覽器窗口進行定位。元素的位置經過 「left」, 「top」, 「right」 以及 「bottom」 屬性進行規定。
relative
:生成相對定位的元素,相對於其正常位置進行定位。所以,」left:20」 會向元素的 LEFT 位置添加 20 像素。
absolute
:生成絕對定位的元素,相對於第一個父元素進行定位 (static 定位除外外)。元素的位置經過 「left」, 「top」, 「right」 以及 「bottom」 屬性進行規定。
上面的b.3示例,views裏host函數,修改成:
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=models.Business.objects.get(id=b) # 效果同樣,只是多了一次數據庫查詢操做 b_id=b ) # renturn render(request, 'host.html') # 每次post提交都會有刷新操做 # 使用render須要返回模板數據,if條件裏的代碼再寫一遍,爲了提升重用性,讓用戶再次訪問。 return redirect('/host')
host.html (部分與上面重複的代碼略,行數太多,有些合併爲一行了),須要加載jQury。
<head> <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{ position: fixed; height: 300px; width: 400px; margin-left: -200px; top:100px; left: 50%; background: white; border: 1px solid red; z-index: 101; } </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> </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> <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="提交" /> <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'); }); }); </script> </body>
上面是經過模態對話框實現的,可是有個弊端,就是彈出框裏一點提交,頁面確定會刷新。若是用戶輸錯,應該顯示錯誤提示,而不是刷新頁面
因此但願有個功能能夠用戶輸完以後,悄悄發送數據給後臺,頁面不刷新。後臺拿到以後再給個回覆。
悄悄提交,用Ajax提交。
這裏Ajax 用jQuery來實現。jquery依賴於xml http request 對象來發的。
$.ajax({ url: '/host', // 提交地址 type: "POST", // 提交方式 data: {'k1': 123,'k2': "root"}, // 提交數據 success: function(data){ // data是服務器端返回的字符串 // 等服務器返回數據後,自動觸發這個函數 var obj = JSON.parse(data); // 把字符串轉換成對象 } })
Ajax請求return 用HttpResponse
obj = JSON.parse(data)
把字符串轉換成對象JSON.stringfy(obj)
前端把對象轉換成字符串host.html 添加:
<form id="add_form" method="POST" action="/host"> . .. ... <input type="submit" value="提交" /> <a id="ajax_submit" >悄悄提交</a> <input id="cancel" type="button" value="取消" /> <span id="erro_msg" style="color: red"></span> </form> <script> $('#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); if(obj.status){ location.reload();; // JS刷新當前頁面 }else{ $('#erro_msg').text(obj.error); } } }) }); </script>
urls.py
url(r'^test_ajax$', views.test_ajax),
views.py
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))
除了$.ajax
,還有$.get
、$.post
、$.getJson
等等,這些方法內部都是調用$.ajax
。
$.get
本質上就是type寫成get。$.get(url="xxx", data={}, success……)
刪除數據的話,能夠後臺刪除數據而且頁面直接remove掉相應的顯示內容,這樣頁面就不用刷新了。
修改下面主要是獲取select下拉框的值作獲取修改
<div class="edit-modal hide"> <form id="edit_form" method="POST" action="/host"> <input type="text" name="nid" style="display:none" /> <!--在用戶點編輯的一剎那,獲取的nid放在這,提交給後臺是那條id的數據。--> <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> $('.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>
假設目前有兩張表,主機表和應用表,
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() 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')
表中添加 ManyToManyField
class Application(models.Model): name = models.CharField(max_length=32) r = models.ManyToManyField("Host")
這樣第三張表Django就幫咱們建立了。這裏表名爲 app01_application_r
,這裏寫了兩個類生成三張表。
總結:通常用哪一種方式?
自動建立關係表,表中只能建立三列數據。想增長額外的列作不到。對於自定義的,自定製功能更好些。
這種添加數據比較簡單,就是表中添加數據那樣。典型的 使用類操做數據庫
models.User.objects.create(hobj_id=1,aobj_id=2)
上面是使用類操做數據庫,可是這裏自動建立的關係表,沒有類,就不能經過類直接操做數據庫。
因此只能經過裏面定義的r進行間接操做。
和以前操做同樣,獲取到r:
obj = models.Application.objects.get(id=1) # 獲取id爲1的application對象 obj.name # 應用名 obj.r # 獲取到 r
獲取到r,裏面有哪些功能呢?
obj = models.Application.objects.get(id=1) # 增長數據 obj.r.add(1) # 添加application id爲1,host id也是1 obj.r.add(2) # 添加application id爲1,host id也是2 obj.r.add(2,3,4) # 增長多條關係1 2,1 3 ,1 4 obj.r.add(*[1,2,3,4]) # 增長列表,增長多條關係1 1 ,1 2,1 3 ,1 4 # 刪除數據 obj.r.remove(1) # 刪除 1 1 記錄 obj.r.remove(2,4) # 刪除 1 2,1 4 記錄 obj.r.remove(*[1,2,3]) # 經過列表刪除 obj.r.clear() # 刪除application id爲1的因此數據 # 更新、修改數據(注意這裏列表不加*) obj.r.set([3,5,7]) # 只存在1 3,1 5,1 7。application id=1的其餘都沒有了 # 查詢數據 obj.r.all() # 全部application id=1的主機對象 「列表」QuerySet類型
views.py
def app(request): if request.method == "GET": app_list = models.Application.objects.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))
urls.py
url(r'^app$', views.app), url(r'^ajax_add_app$', views.ajax_add_app),
app.html
<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> <!--這裏,示例中增長數據,以前是單選的,多對多這裏要改爲多選的。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> <script> $('#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', // 內部 traditional: true, // 獲取到普通字符和列表,不然列表發不到後臺 success: function(obj){ console.log(obj); }, error: function () { // 發到後臺後臺沒有捕捉到,執行的錯誤 } }) }); </script>
下拉框select,默認val獲取單值,若是設了multiple,獲取的就是列表。
轉載請務必保留此出處:http://www.cnblogs.com/lgeng/articles/7365134.html
<!-- END -->
《版權說明》: 本文轉自-- http://blog.csdn.net/fgf00/article/details/53812643