3. Django框架
版本:1.11
创建: django-admin startprojcet xxx cd xxx python manage.py startapp app01 python manage.py runserver 127.0.0.1:8000
今日内容:
1. 请求生命周期
2. 主机管理
- 路由系统
- 视图函数
- ORM(操作数据库)
- 模板
内容详细:
1. 请求生命周期
- 网站本质:socket
服务端(网站):
1. 先启动并监听:80端口
3. 获取请求信息:
获取请求中的URL
根据URL在已经写好的路由关系中进行匹配:
[ /login/ login /index/ index ] def login(request):
请求头
请求体
处理请求
return 响应内容: 响应头 <!DOCTYPE html><html lang="zh-cn">。。。</html>
断开
客户端(浏览器):
https://www.cnblogs.com/news/
2. 发送请求
- 连接:www.cnblogs.com:80
- 发送数据:
GET: GET /news/?page=1&xx=11 http1.1 host:www.cnblogs.com Accept-Encoding:gzip, deflate, br User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 POST: POST /news/?page=1&xx=11 http1.1 host:www.cnblogs.com Accept-Encoding:gzip, deflate, br User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 name=alex&pwd=123
3. 接收响应内容
响应头悄悄写到浏览器
响应体在浏览器上展示
断开
2. 主机管理:部门管理
- 创建procjet和app
- 修改配置文件:
1. 配置
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', ]
2. 模板路径
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', ], }, }, ]
3. 静态文件目录
静态文件 别名
STATIC_URL = '/static/'
物理路径
STATICFILES_DIRS = ( os.path.join(BASE_DIR,'static'), )
- 写代码:
urls.py from app01 import views urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'^login/', views.login), url(r'^index/', views.index), ]
views.py
def login(request): if request.method == "GET": # 请求方法 request.GET else: request.GET # URL中取值 request.POST # 请求体取值 return HttpResponse('...') return redirect('...') return render(request,'模板文件路径',{'k':'v'}) return HttpResponse('欢迎登录') def index(request): return HttpResponse('欢迎登录')
- 创建用户表
models.py
from django.db import models class UserInfo(models.Model): id = models.AutoField(primary_key=True) user = models.CharField(max_length=32) pwd = models.CharField(max_length=64)
settings.py
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config',# "app01" ]
MySQL 连接数据库
settings.py
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'数据库名称', # 记得自己先去创建数据库 'USER': 'root', 'PASSWORD': 'xxx', 'HOST': '127.0.0.1', 'PORT': 3306, } }
procjet.procjet.__init__.py (项目名称下面)
python3 不支持mysqld,但是djaog 默认还是使用mysqldb,所以不要用默认mysqldb,换成pymysql连接数据库
mysql:
import pymysql pymysql.install_as_MySQLdb()
执行原生sql 命令
依赖于models
obj=models.HostsInfo.objects.raw('select * from ops_hostsinfo')
return render(request,'test.html',{'obj':obj})
SQLlite: settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
执行命令:创建数据库表
python3 manage.py makemigrations
python3 manage.py migrate
- 对应关系
类 -> 表
对象 -> 行
- 数据库操作总结:
表级别:
from django.db import models
# 类对象数据库的表
class UserInfo(models.Model):
# 字段对应数据库中列
id = models.AutoField(primary_key=True) # 创建id列,自增,int,主键 user = models.CharField(max_length=32,null=False) # varchar(32) pwd = models.CharField(max_length=64) age = models.IntegerField() # int类型
class Department(models.Model): """ 部门表 """ class Department(models.Model):
"""
部门表
"""
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
python manage.py makemigrations
python manage.py migrate
行:
增加:
models.UserInfo.objects.create(user="alex",pwd='123',age=18) dic = {'user':'alex','pwd':'123',"age":18 } models.UserInfo.objects.create(**dic)
models.UserInfo.objects.filter(id=12,name='alex').update(user='11111',pwd='xxxx') models.UserInfo.objects.filter(**{...}).update(**{...})
删除:
models.UserInfo.objects.filter(id=12,name='alex').delete() dic = {'user':'alex','pwd':'123',"age":18 } models.UserInfo.objects.filter(**dic).delete()
修改:
models.UserInfo.objects.filter(id=12,name='alex').update(user='11111',pwd='xxxx') models.UserInfo.objects.filter(**{...}).update(**{...})
查看:
# [obj,obj,obj,....] v = models.UserInfo.objects.all() # [obj,obj,obj,....] v = models.UserInfo.objects.filter(....) # obj models.UserInfo.objects.filter(....).first() # 获取一个对象;无、多都会报错 models.UserInfo.objects.get(id=1,name='alex')
3. 知识点总结
1. 路由系统
a. url添加起始和终止符 url(r'^example/$', views.example), url(r'^example/add/$', views.example_add),
b. 传参
# 方式一
# http://127.0.0.1:8000/example_edit/?nid=11&xid=1 url(r'^example_edit/$', views.example_edit) def example_edit(request): nid = request.GET.get('nid') xid = request.GET.get('xid') print(nid,xid) return HttpResponse('编辑')
# 方式二:
# /example_edit/123/111/ url(r'^example_edit/(d+)/(d+)/$', views.example_edit), def example_edit(request,nid,xid): print(nid,xid) return HttpResponse('编辑')
# 方式三:
# /example_edit/123/111/ url(r'^example_edit/(?P<xid>d+)/(?P<nid>d+)/$', views.example_edit), def example_edit(request,nid,xid): print(nid,xid) return HttpResponse('编辑')
c. 路由分发
s19day17/urls.pyt url(r'^cmdb/', include('cmdb.urls')) url(r'^openstack/', include('openstack.urls'))
cmdb/urls.py
from django.conf.urls import url,include
from cmdb import views
urlpatterns = [
url(r'^host/$', views.host),
]
openstack/urls.py
from django.conf.urls import url,include
from openstack import views
urlpatterns = [
url(r'^host/$', views.host),
]
欠:
name
namespace
2. 视图函数
def example_edit(request,nid,xid): request.method request.GET request.POST return HttpResponse('文本') return redirect('url') # 打开模板,读取数据到内存 # {'k1':'v1'},对模板中的特殊字符进行“渲染” # 生成不含特殊标签(已经被替换完毕)的字符串 return render(request,'模板路径',{'k1':'v1'})
3. 模板语言
a. 单值
{{ msg }}
b. 索引 .
c. 循环
例如,给定一个运动员列表 athlete_list 变量,我们可以使用下面的代码来显示这个列表: <ul> {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} </ul>
d. 判断
{# 如果 a1 == a2 则显示 #} {% ifequal a1 a2 %} <h1>equal!</h1> {% else %} <h1>not equal!</h1> {% endifequal %} {# 如果 a1 != a2 则显示 #} {% ifnotequal a1 a2 %} <h1>not equal!</h1> {% endifnotequal %} {# 如果 a1 == 'word' 则显示 #} {% ifequal a1 'word' %} <h1>a1=word</h1> {% endifequal %} {# 如果 a2 == 55.23 则显示 #} {% ifequal a2 55.23 %} <h1>a2=55.23</h1> {% endifequal %} {# 如果 a3 == {{ a4 }} 则显示 #} {% ifequal a2 {{ a4 }} %} <h1>a2={{ a4 }}</h1> {% endifequal %} 注意结束使用endifequal或者endifnotequal。 可以使用 if 标签的“==”比较来代替此标签,如: {% if a1 == 'a' %} <h1>a1=a2</h1> {% endif %}
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> #只循环key <p> {% for k in user_list.keys %} <li>{{ k }}</li> {% endfor %} </p> #只循环values <p> {% for val in user_list.values %} <li>{{ val}}</li> {% endfor %} </p> #全都循环出来 <p> {% for k,val in user_list.items %} <li>{{ k}}-{{ val }}</li> {% endfor %} </p>
模板语言--案例
<select name="dep"> {##这里用到 模板的for循环和if判断 。for循环不介绍了,if 的意思是如果第当前选择的那个部门等于全部部门中,那么加上selected 标签,也就是默认选中标签#} {% for dep_title in dep %} {% ifequal hosts.depart.title dep_title.title %} <option selected="selected"> {{ hosts.depart.title }} </option> {% else %} <option> {{ dep_title.title }} </option> {% endifequal %} {% endfor %} </select>
{# { #模板语言的if判断,如果为对应数字 则显示对应样式这个图片#} {% if obj.status.id == 1 %} <span style=""><img src="/static/img/Up.gif">UP</span> {% elif obj.status.id == 2 %} <span style=""><img src="/static/img/Down.gif">DOWN</span> {% elif obj.status.id == 3 %} <span style=""><img src="/static/img/Down.gif">RESTART</span> {% elif obj.status.id == 4 %} <span style=""><img src="/static/img/Down.gif">ERROR</span> {% endif %}
e. 母板
创建模板文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/plugins/bootstrap/css/bootstrap.css"> <style> body{ margin: 0; } </style> {% block css %} {% endblock %} </head> <body> <div style="height: 48px;background-color: #1b6d85"> 头部菜单 </div> <div> <div style="float: left; 20%;background-color: #dddddd;height: 500px;"> 菜单 </div> <div style="float: left; 80%"> {% block content %} {% endblock %} </div> </div> {% block js %} {% endblock %} </body> </html>
#这里为引入模板文件
{% extends "layout.html" %} {% block content %} <h1>编辑部门</h1> <form method="post"> <div class="form-group"> <label for="t1">部门名称</label> <input id="t1" type="text" class="form-control" name="title" value="{{ obj.title }}"> </div> <input type="submit" value="修改" class="btn btn-default"> </form> {% endblock %} {% block js %} <script></script> {% endblock %}
欠:模板中函数
- simple_tag - filter - inlustion_tag
#####未补充笔记
urls 页面
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index), url(r'^login/', views.login), ]
views页面
from django.shortcuts import render,redirect from django.http import HttpResponse # Create your views here. import time,datetime def index(request): #返回首页 return HttpResponse("index") def login(request): #如果提交方式为GET则返回login.html if request.method == "GET": return render(request,"login.html") elif request.method == "POST": u = request.POST.get('username') p = request.POST.get('password') if u == 'sunkd' and p == 'sunkd': #如果密码正确返回首页 return redirect('/index/') else: #如果不正确返回登录页面 return render(request,'login.html') else: #如果为其他请求也返回首页 return redirect('/index/')
前端数据传到后端
前段多选标签传值到后端(getlist 获取到的是一个字典,前段是一个多选框)
u = request.POST.get('username') p = request.POST.get('password') print(u) city = request.POST.getlist('city') print(city)
前端上传文件 传输到后端
因为是上传文件,需要在form表单中加入
enctype="multipart/form-data"
拿的是文件名称
file=request.FILES.get('filename')
print(file)
案例:循环前端过来的文件
import os file=request.FILES.get('filename') #创建上传文件夹,可以判断下 #把上传的文件放到upload 中 file_path=os.path.join('upload',file.name) #打开一个文件 并且写入,chunks 为前端发送,后端接受的块数据 f = open(file_path,mode="wb") for i in file.chunks(): f.write(i) f.close()