python 全栈开发,Day67(Django简介)
昨日内容回顾
- 1. socket创建服务器
- 2. http协议:
- 请求协议
- 请求首行 请求方式 url?a=1&b=2 协议
- 请求头 key:value
- 请求体 a=1&b=2(只有post请求才有请求体)
- 响应协议
- 响应首行 协议 状态码 文本
- 响应头 key:value
- 响应体 html字符串
- 3. wsgiref模块(基于wsgi协议)
- 功能:
- 1. 按着http协议请求格式解析请求数据----envision:{}
- 2. 按着http协议响应格式封装响应数据----response
- 4 基于wsgiref实现了一个简单web框架
- 1. urls : 存放路由关系
- 2 views: 存放视图函数
- 3 templates: 存放html文件
- 4 wsgi-sever:启动文件
一、Django简介
知识预览
MVC与MTV模型
Django的下载与基本命令
基于Django实现的一个简单示例
MVC与MTV模型
MVC
Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:
mvc主要用于web框架,常用的开发语言,有java,php,node.js等等。
web框架应用最广泛就是PHP了,它只能做web开发,而且开发效率很快。
MTV
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:
M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。
T 代表模板 (Template):负责如何把页面展示给用户(html)。
V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:
一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求回去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。
这里面最难的部分就是model,后面会慢慢讲到。
django 有一个ORM,它是专门来操作数据库的。这套语法,需要大量练习才能掌握。
MVC和MTV模型的区别:
- MVC:
- M : model (与数据库打交道)
- V : views (存放html文件)
- C : Controller(逻辑控制部分)
- MTV
- M : model (与数据库打交道)
- T : templates (存放html文件)
- V : views (逻辑处理)
- +
- 路由控制层(分发哪一个路径由哪一个视图函数处理),它没有单独的分层。它作为URL分发器,将url请求分发给不同的view处理
Django的下载与基本命令
1、下载Django:
- pip3 install django
2、创建一个django project
windows用户,以管理员身份打开一个cmd窗口。进入一个空目录,运行以下命令:
- E:\python_script\django框架\day2>django-admin startproject mysite
当前目录下会生成mysite的工程,目录结构如下:
- mysite/
- ├── manage.py
- └── mysite
- ├── __init__.py
- ├── settings.py
- ├── urls.py
- └── wsgi.py
manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库等。
settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
urls.py ----- 负责把URL模式映射到应用程序。
manage.py : 它不关是启动文件,它还是与Django交互的文件。比如:
- python manage.py runserver : 运行项目
- python manage.py startapp : 创建应用
如果运行项目时,不指定端口,默认监听本机的8000端口。
3、在mysite目录下创建应用
- #进入mysite目录
- E:\python_script\django框架\day2>cd mysite
- #创建应用blog
- E:\python_script\django框架\day2\mysite>python manage.py startapp blog
目录结构如下:
- mysite/
- ├── blog
- │ ├── admin.py
- │ ├── apps.py
- │ ├── __init__.py
- │ ├── migrations
- │ │ └── __init__.py
- │ ├── models.py
- │ ├── tests.py
- │ └── views.py
- ├── manage.py
- └── mysite
- ├── __init__.py
- ├── settings.py
- ├── urls.py
- └── wsgi.py
views.py---存放视图函数
models--与数据库打交道
还有一个目录templates,它是用来存放html文件的,下面会讲到。
从上面的目录结构可以看出,mysite目录下有一个blog。那么顶层的mysite,叫做 项目。底层的blog叫做应用。
比如微信是一个项目。聊天,朋友圈,支付...都是应用。
项目是必须包含应用的,项目可以包含多个应用。
mysite下的mysite,是全局文件,它有2个全局配置文件,一个是settings.py(项目配置文件),一个是urls.py(路由控制文件)。
wsgi.py是封装socket,用来接收和响应请求的。这个文件,从来都不需要动。
4、启动django项目
- E:\python_script\django框架\day2\mysite>python manage.py runserver 8080
- Performing system checks...
- System check identified no issues (0 silenced).
- You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
- Run 'python manage.py migrate' to apply them.
- June 21, 2018 - 19:33:29
- Django version 2.0.6, using settings 'mysite.settings'
- Starting development server at http://127.0.0.1:8080/
- Quit the server with CTRL-BREAK.
这样我们的django就启动起来了!当我们访问:http://127.0.0.1:8080/时就可以看到:
基于Django实现的一个简单示例
url控制器
修改mysite目录下的urls.py,增加index路径
注意:index后面不要加括号。直接views.index即可
必须导入blog应用的views模块,否则它找不到对应的视图函数
- from django.contrib import admin
- from django.urls import path
- from blog import views
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('index/',views.index),
- ]
视图
修改blog目录下的views.py,增加index视图函数
- from django.shortcuts import render
- import datetime
- # Create your views here.
- def index(request):
- now=datetime.datetime.now()
- ctime=now.strftime("%Y-%m-%d %X")
- return render(request,"index.html",{"ctime":ctime})
request,它是一个对象。存储了请求信息,比如请求路径,请求方式,GET数据,POST数据...等等。
request参数必须要有,不管你用不用它。
模板
新建文件夹templates,在此目录创建index.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h4>当前时间:{{ ctime }}</h4>
- </body>
- </html>
修改mysite目录下的settings.py,指定模板目录为templates,修改部分如下:
- 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',
- ],
- },
- },
- ]
访问网页,效果如下:
django有一个好处,代码更改之后,它会自动加载代码。而不需要重启django项目,网页就能更新了!
增加登录页面
修改mysite目录下的urls.py,新增一个login
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('index/',views.index),
- path('login/',views.login),
- ]
在templates目录下创建文件login.html
注意:form表单的标签名是form,不是from。from是MySQL的关键字,不要弄混淆了。否则点击提交按钮,是没有反应的。
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <form action="">
- <lable>用户名</lable><input type="text" name="user"/>
- <lable>用户名</lable><input type="password" name="pwd"/>
- <input type="submit">
- </form>
- </body>
- </html>
修改blog目录下的views.py,增加login视图函数
- from django.shortcuts import render
- import datetime
- # Create your views here.
- def index(request):
- now=datetime.datetime.now()
- ctime=now.strftime("%Y-%m-%d %X")
- return render(request,"index.html",{"ctime":ctime})
- def login(request):
- return render(request,"login.html")
访问登录页面,效果如下:
为什么render能找到login.html文件呢?
因为setting.py文件里面定义了template路径。render方法,是用来渲染模板的,它会从TEMPLATES配置的路径中去寻找html文件。
如果修改DIRS里面的文件名,比如改为abc
- 'DIRS': [os.path.join(BASE_DIR, 'abc')],
访问页面,会报错
重新修改回来,再次访问,就正常了。
修改urls.py,增加auth路径,用来做验证的。
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('index/',views.index),
- path('login/',views.login),
- path('auth/',views.auth),
- ]
修改login.html文件,改为post请求
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <form action="/auth/" method="post">
- <lable>用户名</lable><input type="text" name="user"/>
- <lable>用户名</lable><input type="password" name="pwd"/>
- <input type="submit">
- </form>
- </body>
- </html>
修改views.py文件,增加auth视图函数
- from django.shortcuts import render,HttpResponse
- import datetime
- # Create your views here.
- def index(request):
- now=datetime.datetime.now()
- ctime=now.strftime("%Y-%m-%d %X")
- return render(request,"index.html",{"ctime":ctime})
- def login(request):
- return render(request,"login.html")
- def auth(request):
- print(request.path) # 路径
- print(request.method) # 请求方式
- print(request.GET) # GET数据
- print(request.POST) # POST数据
- return HttpResponse("OK")
访问登录页面,输入数据,点击提交
页面输出403,被CSRF拦截了。
CSRF:跨站请求伪造,常缩写为CSRF或者XSRF,是一种对网站的恶意利用。
后面的课程会讲到,如何避免CSRF。修改settings.py里面的MIDDLEWARE 配置项,关闭CSRF
- 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种,GET和POST
在地址栏中,只有GET请求。
在form表单中,有GET和POST。它是根据method属性决定的!一般表单使用POST
再次访问url,输入表单信息,点击提交。
输出ok,表示正常。注意:这里还没有做登录认证,下面会讲到!
查看cmd窗口输出信息:
- /auth/
- POST
- <QueryDict: {}>
- <QueryDict: {'user': ['xiao'], 'pwd': ['']}>
可以看到:
路径:/auth/。请求方式: POST。GET数据为空。POST数据是一个字典。
地址栏直接输入:
http://127.0.0.1:8080/auth/?u=xiao,sex=m
查看cmd窗口输出信息:
- /auth/
- GET
- <QueryDict: {'u': ['xiao,sex=m']}>
- <QueryDict: {}>
登录认证
正常网站,用户名和密码是保存在数据库中。由于还没有学到django连接数据库,所以这里将用户名和密码写死,模拟登录行为。
修改views.py,获取用户和密码,进行判断。
- from django.shortcuts import render,HttpResponse
- import datetime
- # Create your views here.
- def index(request):
- now=datetime.datetime.now()
- ctime=now.strftime("%Y-%m-%d %X")
- return render(request,"index.html",{"ctime":ctime})
- def login(request):
- return render(request,"login.html")
- def auth(request):
- user = request.POST.get('user') # 获取用户名
- pwd = request.POST.get('pwd') # 获取密码
- print(user,pwd)
- #判断用户名和密码
- if user == 'xiao' and pwd == '':
- return HttpResponse("登录成功") # 返回响应体给浏览器,显示"登录成功"文字
- else:
- return render(request,"login.html") # 返回响应体-->login.html文件内容
重新访问登录页面,输入正确的用户名和密码
页面提示,成功。
访问过程分析
访问登录页面时,经历3个步骤
- (1) http://127.0.0.1:8000/login/ get请求 无数据
- (2) path('login/',views.login), 调转视图函数login(request)
- (3) login 执行视图函数,响应了一个login.html页面
解释:
1. 首先是用户在浏览器输入url:http://127.0.0.1:8000/login/
2. django接收到请求之后,根据URL控制器匹配视图函数
3. 执行视图函数login,响应请求给浏览器一个login.html页面。
查看views.py文件的login视图函数
- render(request,"login.html")
上面的代码就是响应体。那么浏览器如何得到response信息的呢?封装response信息是由wsgi来完成的。
点击提交按钮的操作,也经历3个步骤
- (1) http://127.0.0.1:8000/auth/ post请求,数据为user=xiao&pwd=123
- (2) path('auth/',views.auth), 调取视图函数auth(request)
- (3) auth 执行视图函数, if 登陆成功:响应一个字符串登陆成功。else: 响应了一个登陆页面
解释:
1. 虽然form的action属性值为"/auth/",但是执行提交动作时,浏览器会查看action属性,如果为相对路径。那么会获取当前url的域名/IP加端口。和action属性拼接,得到完整的url,比如:http://127.0.0.1:8000/auth/。将表单数据以POST方式发送给此url。
注意:推荐使用这种写法。如果action写成完整的url(比如:http://127.0.0.1:8000/auth/),遇到服务器迁移时。那么涉及到的html文件,都需要更改,非常耗时耗力!
如果采用相对路径方式,那么不需要改动代码,它会自动拼接,完美解决这个问题。
比如写/auth/,会自动拼接为http://127.0.0.1:8000/auth/
如果action为"",也就是空,它会拼接当前的完整ur。
比如访问登录页面,那么action的属性值为 当前url,比如:http://127.0.0.1:8000/login/
2. django接收到请求之后,根据URL控制器匹配视图函数auth
3. 执行视图函数,如果用户名和密码正确,页面显示登录成功。否则,页面还是显示登录页面。
上面提到的2个场景,它们之间,是没有任何关系的。
每一个请求,对于服务器而言,都是一个新的请求。
思考一个问题,能够将login和auth视图函数合并?
答案是可以的。
更改login.html,将action属性设置为空(参考上面的步骤1解释)
- <form action="" method="post">
更改views.py,删除auth视图函数代码,修改login视图函数,完整代码如下:
- from django.shortcuts import render,HttpResponse
- import datetime
- # Create your views here.
- def index(request):
- now=datetime.datetime.now()
- ctime=now.strftime("%Y-%m-%d %X")
- return render(request,"index.html",{"ctime":ctime})
- def login(request):
- #判断请求是否为POST,必须为大写
- if request.method == "POST":
- user = request.POST.get('user') # 获取用户名
- pwd = request.POST.get('pwd') # 获取密码
- print(user, pwd)
- # 判断用户名和密码
- if user == 'xiao' and pwd == '':
- return HttpResponse("登录成功") # 返回响应体给浏览器,显示"登录成功"文字
- else:
- return render(request, "login.html") # 返回响应体-->login.html文件内容
- return render(request,"login.html") # 默认输出登录页面
修改urls.py,删除auth路径
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('index/',views.index),
- path('login/',views.login),
- ]
重新访问登录页面,输入正确的用户和密码,点击提交。页面输出:
这就用到了if分支。
能尽量合成视图函数的,推荐合成。如果逻辑简单,可以合成。
逻辑比较复杂的,还是建议分开。
视图函数,必须返回一个HttpResponse对象。HttpResponse是一个对象,对象里面,放字符串。
HttpResponse会自动将字符串转换为字节
django要求视图函数,必须返回一个HttpResponse对象。
模拟render操作
修改login函数,else部分是重点
- def login(request):
- #判断请求是否为POST,必须为大写
- if request.method == "POST":
- user = request.POST.get('user') # 获取用户名
- pwd = request.POST.get('pwd') # 获取密码
- print(user, pwd)
- # 判断用户名和密码
- if user == 'xiao' and pwd == '':
- return HttpResponse("登录成功") # 返回响应体给浏览器,显示"登录成功"文字
- else:
- from mysite import settings # 导入settings模块
- import os
- # 拼接login.html的绝对路径
- path = os.path.join(settings.BASE_DIR,"templates","login.html")
- with open(path,encoding="utf-8") as f:
- data = f.read() # 读取文件所有内容
- print("data",data+'aaaaa')
- #返回给浏览器并加上一段话
- return HttpResponse(data+'用户名和密码错误')
- # return render(request, "login.html") # 返回响应体-->login.html文件内容
- return render(request,"login.html") # 默认输出登录页面
访问url: http://127.0.0.1:8000/login/
输入一个错误的密码,点击提交
页面输出,用户名和密码错误
那么,render就是干了这些事情。
总结:
对于Django而言,一次请求必须返回一个HttpResponse(字符串)
request对象,存放了请求路径,请求方式,请求数据,比如GET和POST
所以对于视图函数而言,最关心的部分就是request和HttpResponse
一次请求,必有一次响应。如果没有响应,就会报错
范围url: http://127.0.0.1:8000/index/
在视图函数中,render是渲染的意思。那么它是如何工作的呢?
- 1 按着settings-TEMPLATES-DIRS路径找指定文件
- 2 读取文件所有字符串
- 3 渲染: 检查字符串中是否有{{变量}} ,
- if 没有找到:
- HttpResponse(文件字符串)
- else
- 找到 {{变量}},用render第三个参数中的对应值进行相应替换(如果没有找到对应值,{{变量}}替换为空)
- HttpResponse(替换后的文件字符串)
那么渲染的过程,是在后端完成的。不是前端完成的。
看html代码,就知道了。浏览器根本不认识{{变量}},它只能识别html,css,js
注意:如果模板里面,写了{{变量}} 。但是render没传,那么页面中{{变量}} 会被替换为空。
如果模板里面,写了{{ }} 。变量名没写,那么页面报错
如果render传了变量,但是模板里{{变量}} ,变量名写错了,页面中{{变量}} 也会被替换为空。
思考:如何点击时间的时候,变成红色?
直接加行内样式?不对,它是点击的时候,才变成红色。
需要引入jquery来做,修改index.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
- </head>
- <body>
- <h4>当前时间: <span class="time">{{ ctime }}</span></h4>
- <script type="application/javascript">
- $(function(){
- $('.time').click(function () {
- $(this).css("color","red")
- })
- });
- </script>
- </body>
- </html>
访问url: http://127.0.0.1:8000/index/
点击时间,就会变红
但是,线上服务器不能这么干?为什么呢?因为如果一旦jquery访问链接失效。那么整个网站就崩溃了!
所以这种文件,还是需要放到自己的服务器上,才行!
那好办呀,将jquery.min.js放到templates目录。
编辑index.html,直接引入jquery.min.js文件。
- <script src="jquery.min.js"></script>
再次访问页面,怎么点击都没效果,查看控制台,点击网络部分,发现它是404了!
不要以为templates下的文件,可以随便访问。太天真了!
浏览器是不能直接访问templates下的文件,需要Django找到静态文件才行!
在根目录,创建static目录,它是专门存放静态文件的。
将js文件进去。项目目录结构如下:
- mysite/
- ├── blog
- │ ├── admin.py
- │ ├── apps.py
- │ ├── __init__.py
- │ ├── models.py
- │ ├── tests.py
- │ └── views.py
- ├── manage.py
- ├── mysite
- │ ├── __init__.py
- │ ├── settings.py
- │ ├── urls.py
- │ └── wsgi.py
- ├── static
- │ └── jquery.min.js
- └── templates
- ├── index.html
- └── login.html
修改settings.py,最后一行添加,注意:STATIC_URL和它是成对使用的。
- STATIC_URL = '/static/'
- STATICFILES_DIRS = (
- os.path.join(BASE_DIR,"static"),
- )
STATIC_URL参数,表示别名。
STATICFILES_DIRS表示物理路径。
STATIC_URL代指STATICFILES_DIRS定义的路径。
修改index.html,更改src属性
- <script src="/static/jquery.min.js"></script>
注意:这里面的/static/ 是别名,它代指的是物理路径
重新访问页面,再次点击,就会变红。
因为diango利用前缀STATIC_URL的具体内容,来映射STATICFILES_DIRS, 那么它就可以找到具体的文件。
比如前台页面的静态资源路径,一般都是写死了,可能涉及到几百个网页。网站在运营过程中,难免后台服务器,需要做迁移工作,可能和之前的存储路径不一样的。这个时候,让前端去改几百个网页,是一个很繁杂的工作。现在只需要修改STATIC_URL,就可以完美解决这个问题!!!
未完待续...
python 全栈开发,Day67(Django简介)的更多相关文章
- Python全栈开发:django网络框架(一)
Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...
- Python全栈开发:django网络框架(二)
Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行 ...
- python 全栈开发,Day99(作业讲解,DRF版本,DRF分页,DRF序列化进阶)
昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...
- python 全栈开发之路 day1
python 全栈开发之路 day1 本节内容 计算机发展介绍 计算机硬件组成 计算机基本原理 计算机 计算机(computer)俗称电脑,是一种用于高速计算的电子计算机器,可以进行数值计算,又可 ...
- python全栈开发目录
python全栈开发目录 Linux系列 python基础 前端~HTML~CSS~JavaScript~JQuery~Vue web框架们~Django~Flask~Tornado 数据库们~MyS ...
- Python全栈开发相关课程
Python全栈开发 Python入门 Python安装 Pycharm安装.激活.使用 Python基础 Python语法 Python数据类型 Python进阶 面向对象 网络编程 并发编程 数据 ...
- Python 全栈开发【第0篇】:目录
Python 全栈开发[第0篇]:目录 第一阶段:Python 开发入门 Python 全栈开发[第一篇]:计算机原理&Linux系统入门 Python 全栈开发[第二篇]:Python基 ...
- Python全栈开发【面向对象进阶】
Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...
- Python全栈开发【面向对象】
Python全栈开发[面向对象] 本节内容: 三大编程范式 面向对象设计与面向对象编程 类和对象 静态属性.类方法.静态方法 类组合 继承 多态 封装 三大编程范式 三大编程范式: 1.面向过程编程 ...
- Python全栈开发【模块】
Python全栈开发[模块] 本节内容: 模块介绍 time random os sys json & picle shelve XML hashlib ConfigParser loggin ...
随机推荐
- Hadoop基础-HDFS安全管家之Kerberos实战篇
Hadoop基础-HDFS安全管家之Kerberos实战篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们都知道hadoop有很多不同的发行版,比如:Apache Hadoop ...
- Hadoop生态圈-大数据生态体系快速入门篇
Hadoop生态圈-大数据生态体系快速入门篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.大数据概念 1>.什么是大数据 大数据(big data):是指无法在一定时间 ...
- 用 Vue 开发一个简单的答题应用(一)
Vue 之类的 MVVM 框架,能帮助我们用更少的代码实现复杂的业务. 为了简单一点,开发计划分成三阶段: 一,数据写死,实现基本的答题效果.支持多种题型. 二,使用本地存储保存数据,支持题目录入的功 ...
- 使用rownum对oracle分页【原】
以Student表为例进行分页 建表及插入 -- 有表结构如下 create table STUDENT ( sno INTEGER, sname ), sage INTEGER ); -- 插入数据 ...
- JavaScript基本操作之——九个 Console 命令
一.显示信息的命令 console.log('hello'); console.info('信息'); console.error('错误'); console.warn('警告'); 二.占位符 c ...
- keepalive+nginx 热备跟负载均衡
结构图 keepalived配置 master跟backup除了state跟优先级,其它一样,优先级master需大于backup ! Configuration File for keepalive ...
- CentOS6.8安装配置sonarqube6.4
下载最新版本的sonar(现在改名叫sonarqube) https://www.sonarqube.org/downloads/ 我下载的版本是Sonarqube6.4 1 使用前需要 ...
- vue学习起步:了解下
渐进式 有这么一句话,vue是渐进式框架. 抽取“渐进式框架”和“自底向上增量开发的设计”这两个概念是什么?中的解释: 渐进式代表的含义是:主张(主张指使用时的硬性要求)最少.来个对比就知道什么叫主张 ...
- Docker三要素
一.镜像(Image) Docker镜像(Image)就是一个只读的模板,镜像可以用来创建Docker容器,一个镜像可以创建很多容器. Docker 面向对象 镜像 类(class) 容器 实例对象 ...
- jQuery-contextMenu使用教程
jQuery-contextMenu使用教程 效果如下图所示.在[右击菜单]处右击,会出现下面的效果. 添加引用 <script src="jQuery-contextMenu-mas ...