Django(三)
1、Django请求的生命周期
路由系统 -> 视图函数(获取模板+数据-->渲染) -> 字符串返回给用户
2、路由系统
/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" %}
3、视图
FBV:函数
def index(request,*args,**kwargs):
..
CBV:类
class Home(views.View):
def get(self,reqeust,*args,**kwargs):
..
获取用户请求中的数据:
request.POST.get
request.GET.get
reqeust.FILES.get()
# checkbox,
........getlist()
request.path_info
文件对象 = reqeust.FILES.get()
文件对象.name
文件对象.size
文件对象.chunks()
# <form 特殊的设置></form>
给用户返回数据:
render(request, "模板的文件的路径", {'k1': [1,2,3,4],"k2": {'name': '张扬','age': 73}})
redirect("URL")
HttpResponse(字符串)
4、模板语言
render(request, "模板的文件的路径", {'obj': 1234, 'k1': [1,2,3,4],"k2": {'name': '张扬','age': 73}})
<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 %}
{{ row }}
{% endfor %}
{% for row in k2.values %}
{{ row }}
{% endfor %}
{% for k,v in k2.items %}
{{ k }} - {{v}}
{% endfor %}
</body>
</html>
5、ORM
a. 创建类和字段
class User(models.Model):
age = models.IntergerFiled()
name = models.CharField(max_length=10)#字符长度
Python manage.py makemigrations
python manage.py migrate
# settings.py 注册APP
b. 操作
增
models.User.objects.create(name='qianxiaohu',age=18)
dic = {'name': 'xx', 'age': 19}
models.User.objects.create(**dic)
obj = models.User(name='qianxiaohu',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)
6、获取单表单数据的三种方式(views.py )
def business(request):
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 ,内部元素都是元组
return render(request, 'business.html', {'v1': v1,'v2': v2, 'v3': v3})
特别注意
# 获取到的一个对象,如果不存在就报错
models.Business.objects.get(id=1)
但可以用下面的方式来获取对象
对象或者None = models.Business.objects.filter(id=1).first()
代码示例如下:
from django.shortcuts import render, HttpResponse, redirect from app01 import models import json # Create your views here. def business(request): v1 = models.Business.objects.all() v2 = models.Business.objects.all().values('id', 'caption', 'code') v3 = models.Business.objects.all().values_list('id', 'caption', 'code') return render(request, 'business.html', {'v1': v1, 'v2': v2, 'v3': v3}) 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): 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))
from django.db import models # Create your models here. class Business(models.Model): 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(db_index=True) port = models.IntegerField() b = models.ForeignKey(to="Business",to_field='id')
<!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, .delete-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 }}"> <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="提交"/> <a id="ajax_submit">悄悄提交</a> <input id="cancel" type="button" value="取消"/> <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> <input id="ajax_submit_cancel" type="button" value="取消"/> </form> </div> <div class="delete-modal hide"> <form id="delete_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="submit_delete">确认删除</a> <input id="submit_cancle" 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()}, data: $('#add_form').serialize(), success: function (data) { var obj = JSON.parse(data); 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() }); */ // modeletes.Host.objects.filter(nid=nid).update() }); $('#ajax_submit_cancel').click(function () { $('.shade,.edit-modal').addClass('hide'); }); $('.delete').click(function () { $('.shade,.delete-modal').removeClass('hide'); var bid = $(this).parent().parent().attr('bid'); var nid = $(this).parent().parent().attr('hid'); $('#delete_form').find('select').val(bid); $('#delete_form').find('input[name="nid"]').val(nid); }); $('#submit_cancle').click(function () { $('.shade,.delete-modal').addClass('hide'); }); }) </script> </body> </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 }}- {{ row.code }}</li> {% endfor %} </ul> <h1>业务线列表(元组)</h1> <ul> {% for row in v3 %} <li>{{ row.0 }} - {{ row.1 }}- {{ row.2 }}</li> {% endfor %} </ul> </body> </html>
"""s14day20 URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.10/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ 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), url(r'^ajax_add_app$', views.ajax_add_app), # url(r'^business_add', views.business), ]
7、 一对多块表操作的的三种方式(views.py )
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') -->sep间隔符显示
# 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})
8、外键:
v = models.Host.objects.filter(nid__gt=0)
v[0].b.caption ----> 通过.进行跨表
外键:
class UserType(models.Model):
caption = models.CharField(max_length=32)
id caption
# 1,普通用户
# 2,VIP用户
# 3, 游客
class User(models.Model):
age = models.IntergerFiled()
name = models.CharField(max_length=10)#字符长度
# user_type_id = models.IntergerFiled() # 约束,
user_type = models.ForeignKey("UserType",to_field='id') # 约束,
name age user_type_id
# 张扬 18 3
# 张A扬 18 2
# 张B扬 18 2
9、 Ajax
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
不是新的编程语言,而是一种使用现有标准的新方法。
最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
工作原理
常用的参数:
var configObj = {
method //数据的提交方式:get和post
url //数据的提交路径
async //是否支持异步刷新,默认是true
data //需要提交的数据
dataType //服务器返回数据的类型,例如xml,String,Json等
success //请求成功后的回调函数
error //请求失败后的回调函数
}
实例:
$.ajax({
url: '/host',
type: "POST",
data: {'k1': 123,'k2': "root"},
success: function(data){
// data是服务器端返回的字符串
var obj = JSON.parse(data);
}
})
建议:永远让服务器端返回一个字典
return HttpResponse(json.dumps(字典))
10、多对多:
创建多对多:
方式一:自定义关系表
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')
# 10
class Application(models.Model):
name = models.CharField(max_length=32)
# 2
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')
# 10
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)
obj.r.add(2)
obj.r.add(2,3,4)
obj.r.add(*[1,2,3,4])
obj.r.remove(1)
obj.r.remove(2,4)
obj.r.remove(*[1,2,3])
obj.r.clear()
obj.r.set([3,5,7])
# 所有相关的主机对象“列表” QuerySet
obj.r.all()
代码示例如下:
"""s14day20 URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.10/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ 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), url(r'^ajax_add_app$', views.ajax_add_app), # url(r'^business_add', views.business), ]
<!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', // 内部 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>
from django.shortcuts import render,HttpResponse,redirect from app01 import models import json # Create your views here. 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.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) 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 ) return redirect('/host') 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))
知识点补充
Forloop
django模板{%for%}中的forloop的应用
{% for k, v in data.items %}
{{ k }}: {{ v }}
{% endfor %}
这里假设data.items这个列表类似:[ [a,b],[c,d],[e,f]......]这种类型。那么我们可以使用{% for key, value in data.items %}这种方式得到每个元素的列表中的值。
forloop.counter 表示当前迭代数(第几次循环)从1开始
forloop.counter0 同上,但是从0开始
forloop.first 判断此次循环是否是第一次循环,是则返回True
forloop.parentloop 是在嵌套循环中,对父循环中的forloop对象的引用