WEEK18:django 博客开发1
- JS正则
- 定义正则表达式
- /.../ 用于定义正则表达式
- /.../g 表示全局匹配
- /.../i 表示不区分大小写
- /.../m 表示多行匹配
JS正则匹配时本身就是支持多行,此处多行匹配只是影响正则表达式^和$,m模式也会使用^$来匹配换行的内容)
1 var pattern = /^Java\w*/gm; 2 var text = "JavaScript is more fun than \nJavaEE or JavaBeans!"; 3 result = pattern.exec(text) 4 result = pattern.exec(text) 5 result = pattern.exec(text)
#注:定义正则表达式也可以 reg= new RegExp()
- 匹配
JavaScript中支持正则表达式,其主要提供了两个功能
- test(string) 检查字符串中是否和正则匹配
1 n = 'uui99sdf' 2 reg = /\d+/ 3 reg.test(n) ---> true 4 # 只要正则在字符串中存在就匹配,如果想要开头和结尾匹配的话,就需要在正则前后加 ^和$
- exec(string) 获取正则表达式匹配的内容,如果未匹配,值为null,否则,获取匹配成功的数组
获取正则表达式匹配的内容,如果未匹配,值为
null
,否则,获取匹配成功的数组
非全局模式
获取匹配结果数组,注意:第一个元素是第一个匹配的结果,后面元素是正则子匹配(正则内容分组匹配)
1 var pattern = /\bJava\w*\b/; 2 var text = "JavaScript is more fun than Java or JavaBeans!"; 3 result = pattern.exec(text) 4 5 var pattern = /\b(Java)\w*\b/; 6 var text = "JavaScript is more fun than Java or JavaBeans!"; 7 result = pattern.exec(text)
全局模式
需要反复调用exec方法,来一个一个获取结果,直到匹配获取结果为
null
表示获取完毕
1 var pattern = /\bJava\w*\b/g; 2 var text = "JavaScript is more fun than Java or JavaBeans!"; 3 result = pattern.exec(text) 4 5 var pattern = /\b(Java)\w*\b/g; 6 var text = "JavaScript is more fun than Java or JavaBeans!"; 7 result = pattern.exec(text)
- test(string) 检查字符串中是否和正则匹配
- 字符串中相关方法
- obj.search(regexp) 获取索引位置,搜索整个字符串,返回匹配成功的第一个位置(g模式无效)
- obj.match(regexp) 获取匹配内容,搜索整个字符串,获取找到第一个匹配内容,如果正则是g模式找到全部
- obj.replace(regexp, replacement) 替换匹配替换,正则中有g则替换所有,否则只替换第一个匹配项,
- $数字:匹配的第n个组内容;
- $&:当前匹配的内容;
- $`:位于匹配子串左侧的文本;
- $':位于匹配子串右侧的文本
- $$:直接匹配$符号
- 定义正则表达式
- Bootstrap
- 响应式
css属性 @media
@media(min-width:700px){css样式} 浏览器宽度小于700的时候css样式才生效 - 图标字体
@font-face - 基本使用
在引用别人网页时,修改css样式,想让自己的样式不管放在什么位置均生效,需要在样式之后、分号之前加 !important
例如:border-radius:0 !important;
- 响应式
- web框架的本质
所有的Web应用,本质上是socket服务端,用户的浏览器就是socket客户端
1 import socket 2 3 def handle_request(client): 4 buf = client.recv(1024) 5 client.send("HTTP/1.1 200 OK\r\n\r\n") 6 client.send("Hello, Seven") 7 8 def main(): 9 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 10 sock.bind(('localhost',8000)) 11 sock.listen(5) 12 13 while True: 14 connection, address = sock.accept() 15 handle_request(connection) 16 connection.close() 17 18 if __name__ == '__main__': 19 main()
- WSGI是一种规范,定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦
python标准库提供的独立WSGI服务器称为wsgiref
1 from wsgiref.simple_server import make_server 2 3 def RunServer(environ, start_response): 4 # environ 客户端发来的所有数据 5 # start_response 封装要返回给用户的数据,响应头状态 6 start_response('200 OK', [('Content-Type', 'text/html')]) 7 # 返回的内容 8 # return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ] 9 return ['<h1>Hello, web!</h1>'.encode('utf-8'), ] 10 11 if __name__ == '__main__': 12 httpd = make_server('', 8000, RunServer) 13 print("Serving HTTP on port 8000...") 14 httpd.serve_forever()
- WSGI是一种规范,定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦
- 自定义的Web框架
- 框架
通过python标准库提供的wsgiref模块开发一个自己的Web框架
1 from wsgiref.simple_server import make_server 2 3 from View import account 4 5 URL_DICT={ 6 "/index":account.handle_index(), 7 "/date":account.handel_date() 8 } 9 10 def RunServer(environ, start_response): 11 # environ 客户端发来的所有数据 12 # start_response 封装要返回给用户的数据,响应头状态 13 start_response('200 OK', [('Content-Type', 'text/html')]) 14 current_url=environ['PATH_INFO'] 15 func=None 16 if current_url in URL_DICT: 17 func=URL_DICT[current_url] 18 if func: 19 return func 20 else: 21 return ['<h1>404</h1>'.encode('utf-8'), ] 22 # 返回的内容 23 # return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ] 24 return ['<h1>Hello, web!</h1>'.encode('utf-8'), ] 25 26 if __name__ == '__main__': 27 httpd = make_server('', 8000, RunServer) 28 print("Serving HTTP on port 8000...") 29 httpd.serve_forever()
1 # View--account.py 2 def handle_index(): 3 import time 4 v=str(time.time()) 5 f=open("Template/index.html",mode="rb") 6 date=f.read() 7 f.close() 8 date=date.replace(b"@time",v.encode("utf-8")) 9 return [date, ] 10 11 def handel_date(): 12 return ['<h1>Hello, Date!</h1>'.encode('utf-8'), ]
1 <!--Template--index.html--> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <meta charset="UTF-8"> 6 <title>Title</title> 7 </head> 8 <body> 9 <h1>NOW Time: @time </h1> 10 </body> 11 </html>
- 框架
- Django
- 步骤
- 创建Django工程
django-admin startproject 工程名 - 创建APP
cd 工程名
python manage.py startapp APP名称 - 静态文件
工程名/settings.pu
#静态文件位置设置 STATICFILES_DIRS=[( os.path.join(BASE_DIR,'static') )]
- 模板路径
settings.py中的变量TEMPLATES[],在其中的‘DIRS’这个列表中添加“'DIRS': [os.path.join(BASE_DIR, 'html模板路径')]” - 禁用csrf
settings.py中的变量MIDDLEWARE=[],将'django.middleware.csrf.CsrfViewMiddleware'注释掉 - 定义路由规则
在urls.py中urlpatterns=[]中添加函数名 - 定义视图函数
在APP目录下的views.py中定义视图函数
用户提交的方式:request.method
从POST请求中取值:request.POST.get('',None)
从GET请求中取值:request.GET.get('',None)
返回字符串:return HttpResponse("字符串") #from django.shortcuts import HttpResponse
返回模板:return render(request,html模板路径) #from django.shortcuts import render
跳转:return redirect(‘/URL路径’) #from django.shortcuts import redirect - 模板渲染
- {{变量名}}
在函数返回render时使用变量替换html文件中的 {{变量名}} - For循环
{% for row in user_list%}
<li>{{ row }}</li>
{% endfor %} - 索引
列表: user_list.索引值
字典: user_dict.键值(for循环取键、值、键值对:keys,values,items) - 条件判断
{% if 条件 %}
{% if 条件2 %}
{% else %}
{% endif %}
{% else %}
{% endif %}
- {{变量名}}
- 创建Django工程
- 运行项目 python manage.py runserver 127.0.0.1:8001 #默认为8000端口,通过添加地址和端口可以更改默认端口
- 目录结构
- mysite
- mysite # 对整个程序进行配置
- __init__.py
- settings.py # 配置文件
- urls.py # URL对应关系
- wagi.py # 遵循WSGI规范,上线一般使用uwsgi+nginx
- manage.py # 管理Django程序:
- python manage.py # 运行服务端
- python manage.py startapp xx # 创建app目录xx
- python manage.py makemigrations
- python manage.py migrate
- db.sqlite3
- app目录
- migrations # 数据修改表结构的记录
- admin.py # Django为我们提供的后台管理
- apps.py # 配置当前app
- models.py # 创建数据库表,ORM,通过命令可以创建数据库结构
- tests.py # 单元测试
- views.py # 业务逻辑代码(真正写代码的地方)
- mysite # 对整个程序进行配置
- mysite
- 配置
- 配置模板路径
- templates路径,使用“from django.shortcuts import render”默认的文件夹为templates,
可以在settings.py中的“TEMPLATES = []”这个列表中修改,
主要是修改下面这句话:“'DIRS': [os.path.join(BASE_DIR, 'templates')]”,templates为文件夹名字
- templates路径,使用“from django.shortcuts import render”默认的文件夹为templates,
- 配置静态文件路径
- 在settings.py末尾添加下面这句话:
1 STATICFILES_DIRS=[( 2 os.path.join(BASE_DIR,'static') #static为文件夹的名字,此变量必须为列表,默认使用static 3 )]
- 在templates中的html文件中引用时,添加下面两句话:
“<link rel="stylesheet" href="/static/commons.css">”
“<script src="/static/jquery.min.js"></script>”
- 在settings.py末尾添加下面这句话:
- 在settings.py中注释掉“MIDDLEWARE = []”中的“'django.middleware.csrf.CsrfViewMiddleware'”,解决提交表单是提示“CSRF”跨站伪造的错误
- 在login.html网页中的提交表单<form>标签中的action的值必须使用“/”作为结尾,否则报错如下:
“RuntimeError: You called this URL via POST, but the URL doesn’t end in a slash and you have APPEND_SLASH set.”
此问题出现的根本原因为:
在login.html中的form表单中的中action变量值使用"/"结尾
和urls.py中的urlpatterns=[]变量中的path中的第一个值使用“/”结尾
这两处要么都是用“/”结尾,要么都不用
- 配置模板路径
- 重要代码如下:
- views.py
#views.py from django.shortcuts import render # Create your views here. from django.shortcuts import HttpResponse from django.shortcuts import render from django.shortcuts import redirect #重定向使用的模块 def login(request): #包含用户提交的所有信息 #获取用户提交方法 error_msg = "" # print(request.method) #获取用户提交的方法是get还是post if request.method=="POST": #下面这种方法,如果变量不存在会报错 # user=request.POST['user'] # pwd=request.POST['pwd'] # print(user,pwd) #下面这种方法变量不存在则为None user=request.POST.get('user',None) pwd = request.POST.get('pwd',None) # print(user,pwd) if user=='root' and pwd=="123": #用户名密码正确 # 去跳转 return redirect("/home/") else: #用户密码不匹配 error_msg = "用户名或密码错误" return render(request, "login.html",{"error_msg": error_msg}) #将数据库中的用户信息返回给后端管理界面 USER_LIST=[ {"username":"alex","email":"123@sc.com","gender":"男"}, {"username":"qaz","email":"1sdf@sc.com","gender":"女"}, {"username":"wsx","email":"12fgh@sc.com","gender":"男"}, ] def home(request): if request.method=="POST": #获取用户提交的数据 u = request.POST.get("username") e = request.POST.get("email") g = request.POST.get("gender") temp={"username":u,"email":e,"gender":g} USER_LIST.append(temp) return render(request,"home.html",{"user_list":USER_LIST}) # def login(request): # # f=open("templates/login.html","r",encoding="utf-8") # # data=f.read() # # f.close() # # return HttpResponse(data) # return render(request,"login.html")
- urls.py
#urls.py from django.contrib import admin from django.urls import path from django.shortcuts import HttpResponse from cmdb import views def home(request): import datetime # return HttpResponse("<h1>Hello</h1>") # return HttpResponse(str(datetime.datetime.now())) return HttpResponse("<script>alert('当前时间为:{time}');</script>".format(time=str(datetime.datetime.now()))) urlpatterns = [ path('admin/', admin.site.urls), path('h.html/', home), path('login/', views.login), path('home/',views.home) ]
- login.html
<!--login.html--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/commons.css"> <style> label{ width: 80px; text-align: right; display: inline-block; } </style> </head> <body> <!--action="/login/" login后面必须添加“/”,否则提交报错--> <form action="/login/" method="post"> <p> <label for="username">用户名:</label> <!--提交表单中必须添加name元素,否则提交之后无法获取--> <input id="username" name="user" type="text" /> </p> <p> <label for="password">密码:</label> <input id="password" name="pwd" type="password" /> <input type="submit" value="提交" /> <!--用于接收服务端返回的信息--> <span style="color: red;">{{ error_msg }}</span> </p> </form> <script src="/static/jquery.min.js"></script> </body> </html>
- home.html
<!--home.html--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div style="height: 48px;background-color: #dddddd"></div> <div> <form action="/home/" method="post"> <input type="text" name="username" placeholder="用户名"> <input type="text" name="email" placeholder="邮箱"> <input type="text" name="gender" placeholder="性别"> <input type="submit" value="添加"> </form> </div> <div> <table> <!--html中的for循环,用for开始,使用endfor结束--> {% for row in user_list %} <tr> <td>{{ row.username }}</td> <td>{{ row.gender }}</td> <td>{{ row.email }}</td> </tr> {% endfor %} </table> </div> </body> </html>
- views.py
- 步骤
仰天大笑出门去,吾辈岂是蓬蒿人!