WEB框架本质是一个socket #########WEB框架(代码文件结构) MVC Model View Controller 数据库 模板文件 业务处理 MTV Model Template View 数据库 模板文件 业务处理 ############## WEB:MVC、MTV
import socket #WEB框架本质-->socket def handle_request(client): buf = client.recv(1024) client.send(b"HTTP/1.1 200 OK\r\n\r\n") client.send(b"Hello, Seven") def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost', 8000)) sock.listen(5) while True: connection, address = sock.accept() handle_request(connection) connection.close() if __name__ == '__main__': main()
1 from wsgiref.simple_server import make_server 2 from Controller import accout 3 4 URL_DICT = { 5 '/index': accout.handle_index, 6 '/data': accout.handle_data, 7 } #能够作正则匹配,匹配一类的请求内容 8 9 def RunServer(environ, start_response): 10 # environ 客户端发来的全部数据 11 # start_response 封装要返回给用户的数据,响应头状态 12 start_response('200 OK', [('Content-Type', 'text/html')]) 13 current_url = environ['PATH_INFO'] 14 15 # 返回的内容 16 func = None 17 if current_url in URL_DICT: 18 func = URL_DICT[current_url] 19 if func: 20 return func() 21 else: 22 return ['<h1>404</h1>'.encode('utf-8'), ] 23 else: 24 return ['<h1>404</h1>'.encode('utf-8'), ] 25 26 # if current_url == '/index': 27 # return handle_index() 28 # elif current_url == '/data': 29 # return handle_data() 30 # else: 31 # return ['<h1>404</h1>'.encode('utf-8'), ] 32 33 # return ['<h1>Hello, web!</h1>'.encode('utf-8'),] 34 35 if __name__ == '__main__': 36 httpd = make_server('', 8000, RunServer) 37 print("Serving HTTP on port 8000...") 38 httpd.serve_forever()
1 Django:用Python开发Web站点提供最齐全的Web框架,基于MTV的框架 2 3 pip3 install django 4 5 6 C:\Python35\Scripts 7 8 1、建立Django工程(可使用Pycharm建立) 9 django-admin startproject 【工程名称】 --> 会在当前目录下生成Django工程目录 10 如:django-admin startproject mysite 11 默认建立以下内容 12 mysite 13 - mysite # 对整个程序进行配置 14 - init 15 - settings # 配置文件 16 - url # URL对应关系 17 - wsgi # 遵循WSIG规范,uwsgi + nginx(Django内部没有包含socket) 18 19 - manage.py # 管理Django程序: 20 - python manage.py 21 - python manage.py startapp xx 22 - python manage.py makemigrations 23 - python manage.py migrate 24 25 PS: WSGI (Web Server Gateway Interface) 26 是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦。python标准库提供的独立WSGI服务器称为wsgiref。 27 28 29 2、运行Django功能(可以使用Pycharm运行,添加Djangoserver) 30 python manage.py runserver 127.0.0.1:8001 31 32 ------------------ 33 chouti 34 - chouti 35 - 配置 36 - 主站 app 37 - 后台管理 app 38 ------------------ 39 40 41 3、建立app(进入Django工程根目录,执行以下命令) 42 python manage.py startapp cmdb 43 python manage.py startapp openstack 44 python manage.py startapp xxoo.... 45 46 业务处理代码放入app中(views) 47 app: 48 migrations 修改表结构记录 49 admin Django为咱们提供的后台管理 50 apps 配置当前app 51 models ORM,写指定的类 经过命令能够建立数据库结构 52 tests 单元测试 53 views 业务代码 54 55 4、配置(project.settings.py) 56 57 a、配置模板的路径 58 59 TEMPLATES = [ 60 { 61 'BACKEND': 'django.template.backends.django.DjangoTemplates', 62 63 'DIRS': [os.path.join(BASE_DIR, 'templates')], 64 65 'APP_DIRS': True, 66 'OPTIONS': { 67 'context_processors': [ 68 'django.template.context_processors.debug', 69 'django.template.context_processors.request', 70 'django.contrib.auth.context_processors.auth', 71 'django.contrib.messages.context_processors.messages', 72 ], 73 }, 74 }, 75 ] 76 77 b、配置静态目录(不要忘记逗号) 78 static --> 静态文件目录名字使用static 79 80 STATICFILES_DIRS = ( 81 os.path.join(BASE_DIR, 'static'), 82 ) 83 84 <link rel="stylesheet" href="/static/commons.css" /> 85 86 87 c、CSRF verification failed. Request aborted 报错解决(settings文件内注释csrf) 88 89 MIDDLEWARE = [ 90 'django.middleware.security.SecurityMiddleware', 91 'django.contrib.sessions.middleware.SessionMiddleware', 92 'django.middleware.common.CommonMiddleware', 93 #'django.middleware.csrf.CsrfViewMiddleware', 94 'django.contrib.auth.middleware.AuthenticationMiddleware', 95 'django.contrib.messages.middleware.MessageMiddleware', 96 'django.middleware.clickjacking.XFrameOptionsMiddleware', 97 ] 98 99 5、定义路由规则 100 url.py 101 102 "login" --> 函数名 103 104 105 6、定义视图函数 106 app下views.py 107 108 def func(request): 109 # request.method GET / POST -- 用户提交方式 110 111 # http://127.0.0.1:8009/home?nid=123&name=alex 112 # request.GET.get('',None) # 获取请求发来的而数据 113 114 # request.POST.get('',None) 115 116 # return HttpResponse("字符串") -- 返回字符串 117 # return render(request, "HTML模板的路径") -- 返回给用户模板 118 # return redirect('/只能填URL') -- 跳转,只能填'/URL' 119 120 7、模板渲染 121 特殊的模板语言 122 123 a、{{ 变量名 }} 124 125 视图函数: 126 def func(request): 127 return render(request, "index.html", {'current_user': "alex"}) 128 129 130 模板:index.html 131 ----------- 132 <html> 133 .. 134 <body> 135 <div>{{current_user}}</div> 136 </body> 137 138 </html> 139 140 ====> 最后生成的字符串 141 142 <html> 143 .. 144 <body> 145 <div>alex</div> 146 </body> 147 148 </html> 149 ------------ 150 151 b、For循环 152 def func(request): 153 return render(request, "index.html", {'current_user': "alex", 'user_list': ['alex','eric']}) 154 155 156 index.html 157 ------------ 158 <html> 159 .. 160 <body> 161 <div>{{current_user}}</div> 162 163 <ul> 164 {% for row in user_list %} 165 166 {% if row == "alex" %} 167 <li>{{ row }}</li> 168 {% endif %} 169 170 {% endfor %} 171 </ul> 172 173 </body> 174 175 </html> 176 ------------ 177 178 179 c、索引################# 180 def func(request): 181 return render(request, "index.html", { 182 'current_user': "alex", 183 'user_list': ['alex','eric'], 184 'user_dict': {'k1': 'v1', 'k2': 'v2'}}) 185 186 187 index.html 188 189 <html> 190 .. 191 <body> 192 <div>{{current_user}}</div> 193 194 <a> {{ user_list.1 }} </a> #模板语言中根据索引获取列表内容 195 <a> {{ user_dict.k1 }} </a> #模板语言中根据索引获取字典内容 196 <a> {{ user_dict.k2 }} </a> 197 198 </body> 199 200 </html> 201 202 203 d、条件 ################### 204 205 def func(request): 206 return render(request, "index.html", { 207 'current_user': "alex", 208 "age": 18, 209 'user_list': ['alex','eric'], 210 'user_dict': {'k1': 'v1', 'k2': 'v2'}}) 211 212 213 index.html 214 215 <html> 216 .. 217 <body> 218 <div>{{current_user}}</div> 219 220 <a> {{ user_list.1 }} </a> 221 <a> {{ user_dict.k1 }} </a> 222 <a> {{ user_dict.k2 }} </a> 223 224 {% if age %} 225 <a>有年龄</a> 226 {% if age > 16 %} 227 <a>老男人</a> 228 {% else %} 229 <a>小鲜肉</a> 230 {% endif %} 231 {% else %} 232 <a>无年龄</a> 233 {% endif %} 234 </body> 235 236 </html>
1 django-admin startproject 【工程名称】 2 如:django-admin startproject mysite 3 默认建立以下内容 4 - mysite # 工程 5 - mysite # 对整个程序进行配置 6 - __init__.py 7 - settings.py # 配置文件 8 - urls.py # URL对应关系 9 - wsgi.py # 遵循WSIG规范,wsgi + nginx(Django内部没有包含socket) 10 11 - manage.py # 管理Django程序: 12 - python manage.py 13 - python manage.py startapp xx 14 - python manage.py makemigrations 15 - python manage.py migrate 16 17 PS: WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦。python标准库提供的独立WSGI服务器称为wsgiref。
1 python manage.py runserver 127.0.0.1:8001 2 3 ------------------ 4 chouti 5 - chouti 6 - 配置 7 - 主站 app 8 - 后台管理 app 9 ------------------ 10 11 PS:Python和Django要加环境变量
1 python manage.py startapp cmdb 2 python manage.py startapp openstack 3 python manage.py startapp xxoo.... 4 5 业务处理代码放入app中(views) 6 app: 7 migrations 修改表结构记录 8 admin Django为咱们提供的后台管理 9 apps 配置当前app 10 models ORM,写指定的类 经过命令能够建立数据库结构 11 tests 单元测试 12 views 业务代码
""" Django settings for s14django project. Generated by 'django-admin startproject' using Django 1.10.4. For more information on this file, see https://docs.djangoproject.com/en/1.10/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.10/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'hut(bs^o50n^opj8yneen_sh)m0uvu#sdzr%&eq1x)5p*(tqcz' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'cmdb', ] 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 = 's14django.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', ], }, }, ] WSGI_APPLICATION = 's14django.wsgi.application' # Database # https://docs.djangoproject.com/en/1.10/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } # Password validation # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.10/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.10/howto/static-files/ STATIC_URL = '/static/' # 配置好static静态文件目录,不配置用户访问页面静态文件访问不到 STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) # APPEND_SLASH=True
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 --> 静态文件目录名字使用static STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) <link rel="stylesheet" href="/static/commons.css" />
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', ]
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'dbname', 'USER': 'root', 'PASSWORD': 'xxx', 'HOST': '', 'PORT': '', } } # 注意: # 因为Django内部链接MySQL时使用的是MySQLdb模块,而Python3中还无此模块,因此须要使用pymysql模块来代替。 # 在project下与其同名文件夹下的 __init__.py文件中作以下设置 import pymysql pymysql.install_as_MySQLdb()
1 URL拼接传递参数有两种方式: 2 - 在url后加"?key=value"拼接,能够在视图函数中经过get()获取,如: 3 html文件 4 <a class="detail" href="/index?nid=1">详细信息</a> #id是内置方法,尽可能不要使用id作参数 5 --- 6 urls.py文件 7 url(r'^index/', views.index), #一个url对应函数 8 url(r'^home/', views.Home.as_view()), #一个url对应类,根据method经过反射来执行对应方法 9 10 11 - 在url后加"分隔符value"拼接,在urls.py中经过正则进行匹配(经常使用方法),如: 12 html文件 13 <a class="detail" href="/detail-2-9.html">详细信息</a> 14 --- 15 urls.py文件 16 a、一类url对应函数,"正则匹配"的数据(\d+)交给视图函数(视图函数参数有位置要求) 17 url(r'^detail-(\d+)-(\d+).html', views.detail), 18 19 def func(request, nid, uid): #nid即正则匹配的数据(\d+) 20 pass 21 def func(request, *args): 22 args = (2,9) 23 def func(request, *args, **kwargs): 24 args = (2,9) 25 26 27 b、"正则匹配"的数据"分组"(?P<nid>\d+)交给视图函数(视图函数参数没有位置要求) 28 url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail) 29 30 def func(request, nid, uid): 31 pass 32 33 def funct(request, **kwargs): 34 kwargs = {'nid': 1, 'uid': 3} 35 36 def func(request, *args, **kwargs): 37 args = (2,9) 38 39 40 - PS: 41 def detail(request, *args,**kwargs): 42 pass
1 """s14django URL Configuration 2 3 The `urlpatterns` list routes URLs to views. For more information please see: 4 https://docs.djangoproject.com/en/1.10/topics/http/urls/ 5 Examples: 6 Function views 7 1. Add an import: from my_app import views 8 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 Class-based views 10 1. Add an import: from other_app.views import Home 11 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 Including another URLconf 13 1. Import the include() function: from django.conf.urls import url, include 14 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 """ 16 from django.conf.urls import url 17 from django.contrib import admin 18 from cmdb import views 19 20 urlpatterns = [ 21 url(r'^admin/', admin.site.urls), 22 # url(r'^h.html/', views.home), 23 url(r'^login', views.login), 24 url(r'^home', views.home), 25 ]
from django.conf.urls import url urlpatterns = [ url(r'^index/', views.index), #一个url对应函数 url(r'^home/', views.Home.as_view()), #一个url对应类,根据method经过反射来执行对应方法 ]
from django.views import View class Home(View): #方法名必须小写,支持的方法见源码 def dispatch(self, request, *args, **kwargs): # 调用父类中的dispatch,至关于装饰器功能 print('before') result = super(Home,self).dispatch(request, *args, **kwargs) print('after') return result def get(self,request): print(request.method) return render(request, 'home.html') def post(self,request): print(request.method,'POST') return render(request, 'home.html')
1 html文件 2 <a class="detail" href="/detail-2-9.html">详细信息</a> 3 --- 4 urls.py文件 5 a、一类url对应函数,"正则匹配"的数据(\d+)交给视图函数(视图函数参数有位置要求) 6 url(r'^detail-(\d+)-(\d+).html', views.detail), 7 8 def func(request, nid, uid): #nid即正则匹配的数据(\d+) 9 pass 10 def func(request, *args): 11 args = (2,9) 12 def func(request, *args, **kwargs): 13 args = (2,9) 14 15 16 b、"正则匹配"的数据"分组"(?P<nid>\d+)交给视图函数(视图函数参数没有位置要求) 17 url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail) 18 19 def func(request, nid, uid): 20 pass 21 22 def funct(request, **kwargs): 23 kwargs = {'nid': 1, 'uid': 3} 24 25 def func(request, *args, **kwargs): 26 args = (2,9)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> body{ margin: 0; } .menu{ display: block; padding: 5px; } </style> </head> <body> <div style="height: 48px;background-color: black;color: white"> 红红火火哈哈 </div> <div> <div style="position: absolute;top:48px;bottom: 0;left: 0;width: 200px;background-color: brown;"> <a class="menu" href="/cmdb/user_info/">用户管理</a> <a class="menu" href="/cmdb/user_group/">用户组管理</a> </div> <div style="position:absolute;top:48px;left: 210px;bottom: 0;right: 0;overflow: auto"> <h3>添加用户</h3> <form method="POST" action="/cmdb/user_info/"> <input type="text" name="user" /> <input type="text" name="pwd" /> <select name="group_id"> {% for item in group_list %} <option value="{{ item.uid }}">{{ item.caption }}</option> {% endfor %} </select> <input type="submit" value="添加"/> </form> <h3>用户列表</h3> <ul> {% for row in user_list %} <li> <a href="/cmdb/userdetail-{{ row.id }}/">{{ row.username }}</a> | <span> {{ row.user_group.caption }} </span> <a href="/cmdb/userdel-{{ row.id }}/">删除</a> | <a href="/cmdb/useredit-{{ row.id }}/">编辑</a> </li> {% endfor %} </ul> </div> </div> </body> </html>
#project/urls.py from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^cmdb/', include("app01.urls")), url(r'^monitor/', include("app02.urls")), ] #app01/urls.py from django.conf.urls import url,include from django.contrib import admin from app01 import views urlpatterns = [ url(r'^login/', views.login), ] #app02/urls.py from django.conf.urls import url,include from django.contrib import admin from app02 import views urlpatterns = [ url(r'^login/', views.login), ]
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {#上传文件form作处理enctype="multipart/form-data"#} <form action="/login/" method="POST" enctype="multipart/form-data"> <p> <input type="text" name="user" placeholder="用户名" /> </p> <p> <input type="password" name="pwd" placeholder="密码" /> </p> <p> 男:<input type="radio" name="gender" value="1"/> 女:<input type="radio" name="gender" value="2"/> </p> <p> 男:<input type="checkbox" name="favor" value="11"/> 女:<input type="checkbox" name="favor" value="22"/> </p> <p> <select name="city" multiple> <option value="sh">上海</option> <option value="bj">北京</option> <option value="tj">天津</option> </select> </p> <p> <input type="file" name="fafafa"/> </p> <input type="submit" value="提交"/> </form> </body> </html>
1 app下views.py 2 3 def func(request): 4 # request.method GET / POST -- 用户提交方式 5 6 # http://127.0.0.1:8009/home?nid=123&name=alex 7 # request.GET.get('',None) # 获取请求发来的而数据 8 9 # request.POST.get('',None) 10 11 # return HttpResponse("字符串") -- 返回字符串 12 # return render(request, "HTML模板的路径") -- 返回给用户模板 13 # return redirect('/只能填URL') -- 跳转,只能填'/URL'
1 from django.shortcuts import render 2 3 # Create your views here. 4 from django.shortcuts import HttpResponse 5 from django.shortcuts import render 6 from django.shortcuts import redirect 7 8 def login(request): 9 # 包含用户提交的全部信息 10 # print(request.method) # 获取用户提交方法 11 error_msg = "" 12 #若是请求提交的方法是POST(用户提交的数据) 13 if request.method == "POST": 14 # 获取用户经过POST提交过来的数据(用户提交的数据相似于字典) 15 user = request.POST.get('user',None) #get('user',None)获取user内容,默认为None 16 pwd = request.POST.get('pwd',None) 17 if user == 'root' and pwd == "123": 18 # 去跳转到 19 return redirect('/login') #redirect重定向、跳转 20 else: 21 # 用户密码不配 22 error_msg = "用户名或密码错误" 23 #打开页面并返回给用户,settings文件中配置了html文件的路径TEMPLATES('DIRS': [os.path.join(BASE_DIR, 'templates')]) 24 return render(request,'login.html', {'error_msg': error_msg}) #render找到模板返回给用户 25 26 USER_LIST = [ 27 {'id': 1, 'username': 'alex', 'email': 'asdfasdf', "gender": '男'}, 28 {'id': 2, 'username': 'eriuc', 'email': 'asdfasdf', "gender": '男'}, 29 {"id": 3,'username': 'seven', 'email': 'asdfasdf', "gender": '男'}, 30 ] 31 32 def home(request): 33 print(request.GET.get('nid')) 34 35 if request.method == "POST": 36 # 获取用户提交的数据 POST请求中 37 u = request.POST.get('username') 38 e = request.POST.get('email') 39 g = request.POST.get('gender') 40 temp = {'username': u, 'email': e, "gender": g} 41 USER_LIST.append(temp) 42 return render(request, 'test/home.html', {'user_list': USER_LIST}) 43 44 45 # def login(request): 46 # # string = """ 47 # # <form> 48 # # <input type='text' /> 49 # # </form> 50 # # 51 # # """ 52 # # f = open('templates/login.html', 'r', encoding='utf-8') 53 # # data = f.read() 54 # # f.close() 55 # # return HttpResponse(data) 56 # return render(request,'login.html') 57 58 # def home(request): 59 # return HttpResponse('<h1>CMDB</h1>') 60 61 # 主机管理 62 # 防火墙 63 # 。。。
request.GET.get() request.POST.get() request.FILES.get() PS: GET:http请求默认使用的method,获取数据 POST:能够与GET区分,用来提交数据
request.POST.getlist()
import os from django.shortcuts import render,redirect from django.core.files.uploadedfile import InMemoryUploadedFile def login(request): if request.method == "GET": return render(request, 'login.html') elif request.method == "POST": # 上传文件,form标签作特殊设置 obj = request.FILES.get('fafafa') print(obj,type(obj),obj.name) #文件路径拼接 file_path = os.path.join('upload', obj.name) # 打开文件 f = open(file_path, mode="wb") # obj.chunks()上传文件的块数据 for i in obj.chunks(): f.write(i) f.close() return render(request, 'login.html') else: # PUT,DELETE,HEAD,OPTION... return redirect('/index/')
FBV --> function base view url.py /index/ -> 函数名 view.py def 函数(request): ... CBV --> class base view url.py /index/ -> 类 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^home/', views.Home.as_view()), #根据get或post提交方式在类中执行对应的方法 ] view.py from django.views import View class Home(View): def dispatch(self, request, *args, **kwargs): # 调用父类中的dispatch print('before') result = super(Home,self).dispatch(request, *args, **kwargs) print('after') return result def get(self,request): print(request.method) return render(request, 'home.html') def post(self,request): print(request.method,'POST') return render(request, 'home.html') PS:类的方法名必定要小写,源代码中定义好了方法名 ====》 建议:二者都用
变量: {{ item }} For循环: {% for item in item_list %} {{ item }} {% endfor %} forloop.counter forloop.first forloop.last if语句: {% if ordered_warranty %} {% else %} {% endif %} 母板: {% block title %}{% endblock %} 子板: {% extends "base.html" %} {% block title %}{% endblock %} 帮助方法: {{ item.event_start|date:"Y-m-d H:i:s"}} {{ bio|truncatewords:"30" }} {{ my_list|first|upper }} {{ name|lower }}
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <link rel="stylesheet" href="/static/commons.css" /> 7 <style> 8 label{ 9 width: 80px; 10 text-align: right; 11 display: inline-block; 12 } 13 </style> 14 </head> 15 <body> 16 {#提交数据给login#} 17 <form action="/login" method="post"> 18 <p> 19 {#点击label后input内出现光标#} 20 <label for="username">用户名:</label> 21 <input id="username" name="user" type="text" /> 22 </p> 23 <p> 24 <label for="password">密码:</label> 25 <input id="password" name="pwd" type="password" /> 26 <input type="submit" value="提交" /> 27 {# Django会特殊处理 {{ error_msg }} #} 28 <span style="color: red;">{{ error_msg }}</span> 29 </p> 30 </form> 31 <script src="/static/jquery.min.js"></script> 32 </body> 33 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body style="margin: 0"> 8 <div style="height: 48px;background-color: #dddddd"></div> 9 <div> 10 <form action="/home" method="post"> 11 <input type="text" name="username" placeholder="用户名" /> 12 <input type="text" name="email" placeholder="邮箱"/> 13 <input type="text" name="gender" placeholder="性别"/> 14 <input type="submit" value="添加" /> 15 </form> 16 </div> 17 <div> 18 <table> 19 {# Django模板语言for循环 #} 20 {% for row in user_list %} 21 <tr> 22 <td>{{ row.username }}</td> 23 <td>{{ row.gender }}</td> 24 <td>{{ row.email }}</td> 25 <td> 26 <a href="/detail?nid={{ row.id }}">查看详细</a> | 27 <a class="del" href="#" row-id="{{ row.id }}">删除</a> 28 </td> 29 </tr> 30 {% endfor %} 31 32 </table> 33 </div> 34 <div> 35 <form action="/del_host" method="post"> 36 <input style="display: none" id="nid" type="text" name="nid" /> 37 <p> 38 <input type="submit" /> 39 <input type="botton" /> 40 </p> 41 </form> 42 </div> 43 <script> 44 $('.del').click(function(){ 45 var row_id = $(this).attr('row-id'); 46 //赋值 47 $('#nid').val(row_id); 48 }) 49 </script> 50 </body> 51 </html>
1 def func(request): 2 return render(request, "index.html", { 3 'current_user': "alex", 4 'user_list': ['alex','eric'], 5 'user_dict': {'k1': 'v1', 'k2': 'v2'}}) 6 7 8 index.html 9 10 <html> 11 .. 12 <body> 13 <div>{{current_user}}</div> 14 15 <a> {{ user_list.1 }} </a> #模板语言中根据索引获取列表内容 16 <a> {{ user_dict.k1 }} </a> #模板语言中根据索引获取字典内容 17 <a> {{ user_dict.k2 }} </a> 18 19 </body> 20 21 </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> {#根据索引(key)直接获取值#} {{ user_dict.k1 }} <ul> {#循环的key#} {% for k in user_dict.keys %} <li>{{ k }}</li> {% endfor %} </ul> <ul> {#循环的value#} {% for val in user_dict.values %} <li>{{ val }}</li> {% endfor %} </ul> <ul> {#循环的key和value#} {% for k,row in user_dict.items %} <li>{{ k }}-{{ row }}</li> {% endfor %} </ul> </body> </html>
1 def func(request): 2 return render(request, "index.html", { 3 'current_user': "alex", 4 "age": 18, 5 'user_list': ['alex','eric'], 6 'user_dict': {'k1': 'v1', 'k2': 'v2'}}) 7 8 9 index.html 10 <html> 11 .. 12 <body> 13 <div>{{current_user}}</div> 14 15 <a> {{ user_list.1 }} </a> 16 <a> {{ user_dict.k1 }} </a> 17 <a> {{ user_dict.k2 }} </a> 18 19 {% if age %} 20 <a>有年龄</a> 21 {% if age > 16 %} 22 <a>老男人</a> 23 {% else %} 24 <a>小鲜肉</a> 25 {% endif %} 26 {% else %} 27 <a>无年龄</a> 28 {% endif %} 29 </body> 30 31 </html>
a. 先写类 from django.db import models # app01_userinfo class UserInfo(models.Model): # id列,自增,主键 # 用户名列,字符串类型,指定长度 username = models.CharField(max_length=32) password = models.CharField(max_length=64) b. 注册APP INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', #settings中添加app名,Django才给app生成数据库 ] c. 执行命令(同步结构改动到数据库) #记录对models.py的改动(表结构变化),并在migrations下生成记录文件 python manage.py makemigrations #将改动应用到数据库 python manage.py migrate 注意:缩小列长度要谨慎,超出长度数据会丢失 d. ********** 注意 *********** Django默认使用MySQLdb模块连接MySQL 主动修改成pymysql,在project同名文件夹下的__init__文件中添加以下代码便可: import pymysql pymysql.install_as_MySQLdb()
# Create your models here. # app01_userinfo from django.db import models class UserGroup(models.Model): uid = models.AutoField(primary_key=True) caption = models.CharField(max_length=32,unique=True) ctime = models.DateTimeField(auto_now_add=True, null=True) uptime = models.DateTimeField(auto_now=True, null=True) class UserInfo(models.Model): #必须继承models.Model # id列,自增,主键 (Djiango默认建立) # 用户名列,字符串类型CharField,指定长度max_length # 字符串、数字、时间、二进制 username = models.CharField(max_length=32,blank=True,verbose_name='用户名') password = models.CharField(max_length=60, help_text='pwd') email = models.CharField(max_length=60) test = models.EmailField(max_length=19,null=True,error_messages={'invalid': '请输入密码'}) # user_group_id 数字 user_group = models.ForeignKey("UserGroup",to_field='uid',on_delete=models.CASCADE) # (uid,catption,ctime,uptimew) user_type_choices = ( (1, '超级用户'), (2, '普通用户'), (3, '普普通用户'), ) user_type_id = models.IntegerField(choices=user_type_choices,default=1) #不一样的字符串类型(...Field),给Django的admin表单认证使用的 # test = models.URLField(max_length=19,null=True) # test = models.GenericIPAddressField() # gender = models.CharField(max_length=60, null=True)
字符串******** 不一样的字符串类型,只是给Django的admin表单校验使用的(如自动校验EmailField是不是邮箱格式) CharField(Field) - 字符类型 - 必须提供max_length参数, max_length表示字符长度 TextField(Field) - 文本类型 EmailField(CharField): - 字符串类型,Django Admin以及ModelForm中提供验证机制 IPAddressField(Field) - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制(新版本中废弃,使用GenericIPAddressField) GenericIPAddressField(Field) - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6 - 参数: protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6" unpack_ipv4, 若是指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,须要protocol="both" URLField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证 URL SlugField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、链接符(减号) CommaSeparatedIntegerField(CharField) - 字符串类型,格式必须为逗号分割的数字 UUIDField(Field) - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证 FilePathField(Field) - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能 - 参数: path, 文件夹路径 match=None, 正则匹配 recursive=False, 递归下面的文件夹 allow_files=True, 容许文件 allow_folders=False, 容许文件夹 FileField(Field) - 字符串,路径保存在数据库,文件上传到指定目录 - 参数: upload_to = "" 上传文件的保存路径 storage = None 存储组件,默认django.core.files.storage.FileSystemStorage ImageField(FileField) - 字符串,路径保存在数据库,文件上传到指定目录 - 参数: upload_to = "" 上传文件的保存路径 storage = None 存储组件,默认django.core.files.storage.FileSystemStorage width_field=None, 上传图片的高度保存的数据库字段名(字符串) height_field=None 上传图片的宽度保存的数据库字段名(字符串) 数字******** AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自增列,必须填入参数 primary_key=True 注:当model中若是没有自增列,则自动会建立一个列名为id的列 --- from django.db import models class UserInfo(models.Model): # 自动建立一个列名为id的且为自增的整数列 username = models.CharField(max_length=32) class Group(models.Model): # 自定义自增列 nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) SmallIntegerField(IntegerField): - 小整数 -32768 ~ 32767 PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正小整数 0 ~ 32767 IntegerField(Field) - 整数列(有符号的) -2147483648 ~ 2147483647 PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - 正整数 0 ~ 2147483647 BigIntegerField(IntegerField): - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807 自定义无符号整数字段 class UnsignedIntegerField(models.IntegerField): def db_type(self, connection): return 'integer UNSIGNED' PS: 返回值为字段在数据库中的属性,Django字段默认的值为: 'AutoField': 'integer AUTO_INCREMENT', 'BigAutoField': 'bigint AUTO_INCREMENT', 'BinaryField': 'longblob', 'BooleanField': 'bool', 'CharField': 'varchar(%(max_length)s)', 'CommaSeparatedIntegerField': 'varchar(%(max_length)s)', 'DateField': 'date', 'DateTimeField': 'datetime', 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', 'DurationField': 'bigint', 'FileField': 'varchar(%(max_length)s)', 'FilePathField': 'varchar(%(max_length)s)', 'FloatField': 'double precision', 'IntegerField': 'integer', 'BigIntegerField': 'bigint', 'IPAddressField': 'char(15)', 'GenericIPAddressField': 'char(39)', 'NullBooleanField': 'bool', 'OneToOneField': 'integer', 'PositiveIntegerField': 'integer UNSIGNED', 'PositiveSmallIntegerField': 'smallint UNSIGNED', 'SlugField': 'varchar(%(max_length)s)', 'SmallIntegerField': 'smallint', 'TextField': 'longtext', 'TimeField': 'time', 'UUIDField': 'char(32)', BooleanField(Field) - 布尔值类型 NullBooleanField(Field): - 能够为空的布尔值 DurationField(Field) - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型 FloatField(Field) - 浮点型 DecimalField(Field) - 10进制小数 - 参数: max_digits,小数总长度 decimal_places,小数位长度 二进制******** BinaryField(Field) - 二进制类型 日期、时间******** DateTimeField(DateField) - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] DateField(DateTimeCheckMixin, Field) - 日期格式 YYYY-MM-DD TimeField(DateTimeCheckMixin, Field) - 时间格式 HH:MM[:ss[.uuuuuu]]
auto_now_add 建立时,自动生成时间 auto_now 更新时,自动更新为当前时间 # obj = UserGroup.objects.filter(id=1).update(caption='CEO') #自动时间更新不生效 # obj = UserGroup.objects.filter(id=1).first() #生效 # obj.caption = "CEO" # obj.save() default 数据库中字段的默认值 null 数据库中字段是否能够为空 db_column 数据库中字段的列名 db_tablespace primary_key 数据库中字段是否为主键 db_index 数据库中字段是否能够创建索引 unique 数据库中字段是否能够创建惟一索引 unique_for_date 数据库中字段【日期】部分是否能够创建惟一索引 unique_for_month 数据库中字段【月】部分是否能够创建惟一索引 unique_for_year 数据库中字段【年】部分是否能够创建惟一索引 verbose_name Admin中字段名显示自定义的名字 blank Admin中是否容许用户输入为空 editable Admin中是否能够编辑 help_text Admin中该字段的输入提示信息(显示在该行下边) choices Admin中显示选择框的内容,用不变更的数据放在内存中从而避免跨表操做 注:由于数据存在内存中,若是修改要重启程序才会生效 如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1) error_messages 自定义错误信息(字典类型),从而定制想要显示的错误信息; 字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date 如:{'null': "不能为空.", 'invalid': '格式错误'} validators 自定义错误验证(列表类型),从而定制想要的验证规则 from django.core.validators import RegexValidator from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\ MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator 如: test = models.CharField( max_length=32, error_messages={ 'c1': '优先错信息1', 'c2': '优先错信息2', 'c3': '优先错信息3', }, validators=[ RegexValidator(regex='root_\d+', message='错误了', code='c1'), RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'), EmailValidator(message='又错误了', code='c3'), ] )
class UserInfo(models.Model): nid = models.AutoField(primary_key=True) username = models.CharField(max_length=32) class Meta: # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名 db_table = "table_name" # 联合索引 index_together = [ ("pub_date", "deadline"), ] # 联合惟一索引 unique_together = (("driver", "restaurant"),) # admin中显示的表名称 verbose_name # verbose_name加s verbose_name_plural #更多:https://docs.djangoproject.com/en/1.10/ref/models/options/
1.触发Model中的验证和错误提示有两种方式: a. Django Admin中的错误信息会优先根据Admiin内部的ModelForm错误信息提示,若是都成功,才来检查Model的字段并显示指定错误信息 b. 调用Model对象的 clean_fields 方法,如: # models.py class UserInfo(models.Model): nid = models.AutoField(primary_key=True) username = models.CharField(max_length=32) email = models.EmailField(error_messages={'invalid': '格式错了.'}) # views.py def index(request): obj = models.UserInfo(username='11234', email='uu') try: print(obj.clean_fields()) except Exception as e: print(e) return HttpResponse('ok') # Model的clean方法是一个钩子,可用于定制操做,如:上述的异常处理。 2.Admin中修改错误提示 # admin.py from django.contrib import admin from model_club import models from django import forms class UserInfoForm(forms.ModelForm): username = forms.CharField(error_messages={'required': '用户名不能为空.'}) email = forms.EmailField(error_messages={'invalid': '邮箱格式错误.'}) age = forms.IntegerField(initial=1, error_messages={'required': '请输入数值.', 'invalid': '年龄必须为数值.'}) class Meta: model = models.UserInfo # fields = ('username',) fields = "__all__" class UserInfoAdmin(admin.ModelAdmin): form = UserInfoForm admin.site.register(models.UserInfo, UserInfoAdmin)
根据类对数据库表中的数据进行各类操做 一对多: a. 建立外键(一个对象) b. 数据库中实际存储 --> 外键字段_id c. 根据"外键字段_id"添加数据 models.tb.object.create(name='root', user_group_id=1) d. 显示用户组信息 userlist = models.tb.object.all() for row in userlist: row.id row.user_group_id row.user_group.caption
参考:css