刚开始学习时可在配置文件中暂时禁用csrf中间件,方便表单提交测试。
咱们的django究竟是什么东西呢?css
咱们的代码都是在后台写的,包括咱们的pycharm都是属于后台的工具,可是咱们的后端开发说究竟是须要开发完了以后拿到用户面前的,让咱们的用户看到咱们的东西,首先要让他们看到,而后才可以在看到的基础上来进行一些交互,而后大致的框架就算是搭建成功了,再接下来就是细节的填充,以及功能的扩展,根据业务的发展以及用户的需求去知足,一一实现需求.html
上面说了一通的废话,咱们的django到底跟这一切又有什么关系呢?前端
咱们的代码是后端的东西,它若是放到用户的眼前是须要一些过程的,咱们的前端是可让咱们的用户直观的看到效果,咱们的前端改动一些标签就可让用户明显感觉到差别,因此咱们的前端是跟用户交互更加直接的,可是前端的功能都是一些浮于表面的东西,它是做为装饰的,不少的功能仅仅靠前端是没法实现的,须要后端来进行功能的主要开发,而后前端再在后端的基础上进行页面的渲染,实现用户的交互,那么咱们的前端就须要跟后端关联上,要怎么实现关联上的同时还能不出错的无缝衔接上稳定地投入使用呢?,这个时候就须要咱们的django了,它就是让咱们的前端和后端无缝衔接上的同时,稳定地投入使用,咱们的web框架就是干这个事情的,下面咱们会提到web框架的本质,它最根本的就是socket套接字通讯,咱们开启一个服务端而后它就可以永远稳定地运行下去,接下来咱们的客户端配好了端口和ip地址的时候就可以链接上它,咱们的django就封装的有这个socket套接字功能,它自己就自带套接字通讯功能,因此,你看咱们须要用到的东西在这个django里面通通都会实现,它很牛逼吧,什么都是自带的,然而它还不只仅是这样,它的功能远远比咱们想象得的要强大得多,暂且就理解它为一个封装了超多功能的异常庞大的模块吧,咱们要实现先后端的交互它是少不了的.html5
它里面有超多的封装好的模块.咱们只须要在使用的时候把它想起来而后就跟咱们引入模块或者引入文件的时候同样使用import 就能够引入到你的代码块里面进行使用了java
它核心的三件套是必需要掌握的,一切的功能都是基于这三者来实现的,python
Httpresponse,--负责来响应浏览器的,须要浏览器返回什么就在它里面定义什么便可,浏览器的根本就是返回字符串,因此Httpresponse("str(ok)")这样写就能够mysql
render, --负责接收request参数,而后还有一个渲染的页面(也就是一个HTML标签),以及保存数据用的一个字典数据类型的参数.这个render主要的功能就是渲染页面,在渲染的同时咱们须要把一些参数填充到所渲染的页面里面去,就须要用到这个render功能,[那咱们何时须要使用到参数去填充页面的状况呢,咱们的页面是提早写好的,那是前端的时候,如今咱们须要跟后端进行一些交互,这个时候前端显示的数据就会有所调整,根据特殊的要求来进行调整,这个时候咱们的代码就须要后端来实现了,把后端改好的代码填充到前端去,就须要把前端的页面设置一块地方用来预存参数,当个人后端须要改变功能的时候能够启动到前端预存的那些参数而后进行修改,这个时候就须要使用到填充参数到所渲染的页面中去]jquery
redirect,--负责跳转页面,后端的代码块码完以后咱们想让页面往何处跳转就使用它去跳转,return redirect("/sogo/") 这里就是跳转的页面,之因此这样写,是由于咱们的url域名里面都是这样的格式,https://i.cnblogs.com/EditPosts.aspx?postid=8269914,例如这里的http后面的域名就是这样的格式,web
这里还有一个很重要的点就是request,它是一个参数,是咱们在django里面写函数的时候须要传入的参数,这个参数是干什么用的呢,它里面包裹了大量的信息,都是关于请求的数据信息,sql
全部跟请求相关的数据都是由它来进行接收,咱们的形参就是用来接收各类的参数的,它就是那样的一个形参,它只是接收跟请求相关的参数,咱们之后会学到它的大量的用法,包括都有哪些是跟请求相关的,请求都是有哪些,等等.
老师的笔记:
day61 1.前情回顾 1. pymysql 使用: 安装 pip install pymysql 导入 import pymysql 具体使用: 1. 建立链接 conn = pymysql.connect(host="lcoalhost", port=3306, user="", password="", database="", charset="utf8") 2. cursor = conn.cursor() 3. cursor.execute(sql, (arg1, arg2 ...)) --> SQL注入问题 4. 增删改查 增: cursor.execute("insert into ...", (arg1, arg2...)) conn.commit() --> 向数据库提交 cursor.lastrowid --> 获取刚插入的那条数据的ID 删: cursor.execute(“delete ...”, (arg1, arg2...)) conn.commit() --> 向数据库提交 改: cursor.execute("update ...”, (arg1, arg2...)) conn.commit() --> 向数据库提交 查: cursor.execute(“select ...”, (arg1, arg2...)) cursor.fetchone() --> 查单条数据,元组类型 cursor.fetchmany(n) --> 查多条数据 cursor.fetchall() --> 查全部数据 cursor.scroll(n, mode="relative") --> 相对移动 cursor.scroll(n, mode="absolute") --> 绝对移动 批量执行: cursor.executemany("update ...”, ((arg1, arg2),(arg1, arg2),(arg1, arg2))) conn.commit() 回滚: try: cursor.execute("update ...”, (arg1, arg2...)) conn.commit() --> 向数据库提交 except Exception as e: logging.error(str(e)) conn.rollback() cursor.close() conn.close() 2. 今日内容 Web框架(绝大部份内容) 浏览器 socket客户端 4. 客户端链接服务端 5. send() 客户端发数据 8. recv() 接收服务端回复的数据 9. close() 关闭连接 博客园服务器 socket服务端 1. bind IP和端口 2. listen() 监听 3. accept() 等待链接 6. recv() 接收数据 7. send() 回复数据 FTP上传文件的: msg = "upload|filename|1024" 服务端解析: msg.split() -> 浏览器和你的web服务端通讯须要遵循一个规则,这个规则就是HTTP协议。 HTTP协议: 简单的理解成 规定了消息的格式 浏览器发送 ---> 请求 (request) 服务端回复 ---> 响应 (response) 请求和响应的格式: Header (头)\r\n\r\n Body (体) 请求: GET请求的格式: 只有请求头没有请求体 "GET / HTTP/1.1\r\n k1:v1\r\n k2:v2\r\n .... " POST请求的格式: "POST / HTTP/1.1\r\n k1:v1\r\n k2:v2\r\n .... " Body 响应: Header Body 渲染 (render) 本质上: 用数据去替换HTML页面中的特殊字符 jinja2 Flask 总结: 本身定义的web框架 a. 本身写socket处理请求相关的数据(web服务端) wsgiref uWSGI gunicorn WSGI协议: Python Web服务端和Python 应用程序之间通信的一个标准 b. URL -> 函数 --> 函数里面写业务逻辑(取到数据) c. 把数据填充到HTML页面(字符串替换) 分类: 1. a、b、c都是用本身的 --> Tornado 2. a用别人的,b和c用本身的 --> Django 3. a和c都用别人的,b用本身的 --> Flask 另一个维度的分类: 1. Django (大而全) 2. 其余 (小而精) Django: 安装: pip install django==1.11.9 新建Django项目: 命令行方式: > 先进入到你新建的项目要存放的目录 > django-admin startproject s8 > cd s8 > python manage.py runserver PyCharm方式: File -> new project -> 选Django -> 起名字 -> 点右下角create 启动Django项目: 命令行方式: python manage.py runserver 127.0.0.1:8888 python manage.py runserver 8888 PyCharm方式启动:(PyCharm单独打开你的Django项目) 1. 点页面上方中部位置的绿色小三角 直接运行 Ctrl + C 中止 Django项目目录结构: s8 -s8 -settings.py -urls.py URL --> 函数的对应关系 -wsgi.py -manage.py 新手必备三件套: from django.shortcuts import HttpResponse, render, redirect 跟request相关的方法: request.method request.POST request.POST.get("key") --> 获取对应的值 新建Django项目三件事: 1.注释csrf那一行 2. 配置静态文件 3. 检查templates配置项 3. 今日做业 把你以前用Bootstrap写的那个登陆页面,用Django跑起来 1. 静态文件的摆放位置 ****** 2. 登录用POST提交数据,使用pymysql去数据库里取用户数据校验 3. 登录成功跳转到 http://www.luffycity.com 4. 登陆失败就返回当前页面
day62 1. 前情回顾 1. Django配置相关 1. Templates文件夹配置 --> 存放全部的HTML文件 # HTML页面存放位置 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] # 你的HTML文件的目录 , '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', ], }, }, ] 2. 静态文件 # 在HTML页面上引用静态文件时写的名字 STATIC_URL = '/static/' # 静态文件(CSS文件和JS文件)存放的实际位置 STATICFILES_DIRS = [ os.path.join(BASE_DIR, "xxx"), # F:\PythonS8\day61\mysite\xxx ] 3. 注释掉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. 新手必备三件套 from django.shortcuts import HttpResponse, render, redirect 1. HttpResponse("字符串") 2. render 1. render(request, "html文件") --> 至关于打开HTML文件,读取文件内容,回复给浏览器 2. render(request, "html文件", {"k1": "v1", "k2": "v2"}) --> 至关于打开HTML文件,读取文件内容,使用字符串替换,替换完的内容回复给浏览器 3. redirect("具体要跳转的URL") 3. request这个参数 1. 封装了全部跟请求相关的数据,是一个对象 2. 目前咱们学过 1. request.method GET,POST ... 2. request.POST.get("input name的值") 2. 今日内容 学员管理系统 学生 老师 班级 班级和老师关系表 id 姓名 cid id 姓名 id 名称 id tid cid 1 李岩 1 1 Egon 1 1 1 2 建超 2 2 Eva_J 1 全栈8期 2 1 2 3 晓梅 3 3 WuSir 2 全栈9期 3 2 1 4 Yuan 3 全栈10期 4 4 2 5 4 3 1. 建立班级表 -- 建立班级表 CREATE TABLE class( id INT AUTO_INCREMENT PRIMARY KEY , cname CHAR(20) NOT NULL UNIQUE )ENGINE =innodb DEFAULT CHARSET="utf8"; 2. 建立老师表 -- 建立老师表 CREATE TABLE teacher( id INT AUTO_INCREMENT PRIMARY KEY , tname CHAR(20) NOT NULL UNIQUE )ENGINE=innodb DEFAULT CHARSET="utf8"; 3. 学生表 -- 建立学生表 CREATE TABLE student( id INT AUTO_INCREMENT PRIMARY KEY, sname CHAR(20) NOT NULL UNIQUE , cid INT,FOREIGN KEY (cid) REFERENCES class(id) ON DELETE CASCADE ON UPDATE CASCADE )ENGINE=innodb DEFAULT CHARSET="utf8"; 4. 班级和老师关系表 -- 建立班级和老师关系表 CREATE TABLE class_2_teacher( id INT AUTO_INCREMENT PRIMARY KEY , tid INT, FOREIGN KEY (tid) REFERENCES teacher(id) ON DELETE CASCADE ON UPDATE CASCADE, cid INT, FOREIGN KEY (cid) REFERENCES class(id) ON DELETE CASCADE ON UPDATE CASCADE )engine=innodb DEFAULT CHARSET="utf8"; 模板语言:(jinja2) 如今学到的: 1. {{ 变量名 }} # 咱们的HTML标签里面能够找一个代码逻辑合适的地方就直接写上两个重叠的大括号---{{}},而后在里面写上变量名[即函数里面会用到的参数],若是咱们的变量名是一个字典的话,那么咱们的这个大括号的语法是支持存入这样的自己是一个字典的变量名的,并且支持咱们在取值的时候使用到以下的例子 若是传过来的变量是字典--> p = {"name": "alex", "age": 18} 支持:p.name 和 p.age 取值,通常取值的话都是经过循环来取值的,这里就引出了咱们的下面的循环用法 2. for循环 {% for i in 变量名 %} # 若是咱们的变量名是一个字典的话,咱们是能够经过使用到i.key去取值的,就拿上面的例子来讲,咱们的变量名是p,那么就是{% for i in p %}, {{i.name}}, {{i.age}} {{% endfor %}} {{forloop.counter}} # 这里是从0开始若是这样写就是 # {{forloop.counter1}}从1开始 {{ i }} {% endfor %} {{forloop.counter}} {{forloop.counter0}} GET请求传参数的方式: /xxx/?k1=v1&k2=v2 ? 前面的是URL ?后面的是请求的参数 多个参数之间用&分隔 以下示例: https://i.cnblogs.com/EditPosts.aspx?postid=8269914 EditPosts.aspx?它后面就是key-value的格式,key是postid,value是8269914, 再以下示例:https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_15802839984148081810%22%7D&n_type=0&p_from=4 这里面的key-value对应的有: context = %7B%22nid%22%3A%22news_15802839984148081810%22%7D & # 这里就是分割符, n_type = 0 & p_from = 4 POST请求传数据: 是放在请求体里面的
建立django项目使用cmd命令行执行:
django-admin startproject (项目名,自定义)
建立以后须要执行,也使用cmd命令行实现:
咱们须要把当前目录切换到所建立的项目目录里面去,而后再执行下面的命令行语句,不然会报错:no such file or directory .
切换目录使用cd /d 所建立的项目目录,通常咱们刚刚建立的项目就直接使用cd 项目名称便可直接切换到所建立的项目目录里面去,
python manage.py runserver ip和端口:以下举例:
python manage.py runserver 127.0.0.1:8000
若是你想查看你的django安装的版本或者检查你是否已经安装了django,那么咱们在cmd命令行里面输入如下信息就能够得出结果:
python -m django --version
若是你已经安装了,那么它会有提示你安装的版本,若是没有安装的话它会有错误提示信息:“No module named django”。
咱们在建立django项目的时候在cmd里面,能够先使用cd /d 指定的文件路径,例如: cd /d D:\file 这样就是改变了当前的文件路径,而后咱们再执行建立django项目操做
咱们的django项目建立到执行的简单步骤:
首先咱们的项目建立完以后须要在单独的窗口打开,不能更它的项目一块儿打开
如图所示咱们的项目是单独在一个窗口打开的,
咱们的static是静态文件存放夹,全部的静态文件都是放在这里,咱们能够在static里面创建css文档,js文档,img文档,专门用于存放专门的文件,还有其余的一些存放于plugins中,其余的好比咱们以前写bootstrap用到的相关文档都存放于plugins里面
咱们本身创建的这个文件夹,这个是一开始建立以后就须要创建好的,能够是任何其余的名字,只不过咱们使用这个名字,你们都是约定俗成的,写成这样以后你们都知道它是干什么的,若是写做其余的就只有你本身知道它是干什么的,别人都不知道,这样沟通的成本就会增长,
还有就是在nun_one(这自己就是我给我本身新建的django项目起的名字)里面的py文件里有一个views.py它是咱们本身手动添加上去的,它不是你创建项目的时候就自带的,这里是咱们存放咱们写的后台代码块的地方,全部的后台的代码都是存放于这里的,
还有一个templates它里面存放的都是html文件,全部的html文件都须要存放于这里,这些都是规矩,咱们要想使用django就须要遵照它的规范,而后才能顺利运行它.
setting文件的设置以下:
""" Django settings for nun_one project. Generated by 'django-admin startproject' using Django 1.11.9. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/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.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'go7=2^)p%q!g-dviz#9i7djz6)xf-m#0a7m2)an2)vmty-_o8(' # 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', ] 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 = 'nun_one.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 = 'nun_one.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/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.11/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.11/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.11/howto/static-files/ STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static"), # 咱们须要在设置里面查看咱们的拼接路径, # 这个拼接路径是须要本身手动写的,有问题的话先来看这里的设置路径,先查看咱们的setting # os.path.join(BASE_DIR, "sta") ]
url文件的设置以下:
"""nun_one URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/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 django.shortcuts import HttpResponse, render, redirect # 这里是django的三件套,它的主要核心模块内容,shortcuts是关键字 from .views import index, hm_btst, class_list, \ class_form, add_class, delete_class, edit_class, \ teacher_form, add_teacher, edit_teacher, delete_teacher # 这里咱们须要使用加上. 而后就不会报错,这里是对当前目录作一个限定,咱们须要引用咱们本身写入的模块那么就须要另外起一行去写 urlpatterns = [ url(r'index/', index), # 这里r后面的引号里面不用加上前/,只须要把后/加上便可 url(r'hm_bootstrap/', hm_btst), # 这里的括号里须要写入两个参数,一个是域名, # 放到r后面,而后还有函数名,须要放到域名后面,函数名须要在上面引入才能够,不然这里会报错,不会生效的 url(r'class_list/', class_list), url(r'class_form/', class_form), url(r'add_class/', add_class), url(r'delete_class', delete_class), url(r'edit_class/', edit_class), url(r'teacher_form/', teacher_form), url(r'add_teacher/', add_teacher), url(r'edit_teacher/', edit_teacher), url(r'delete_teacher', delete_teacher), # url(r'^admin/', admin.site.urls), ]
views文件里面是咱们写好的后端代码块:
import pymysql from django.shortcuts import HttpResponse, render, redirect def index(request): # return HttpResponse("ok") error_msg = "" # 咱们以前就是把这里的变量放到了下面的if判断里面了, # 然而咱们的method多是post也多是get,因此须要把这里的变量放到if判断外面, # 这样就是全局的变量了,这样咱们的get和post均可以使用到它, # 而咱们以前就是把它定义到了if判断下面了,不只仅是放到了if post下面并且还放到了 # if post下面的else里面,就至关于它的做用域就更加狭窄了,因此咱们报错就会显示咱们的这个变量没有被定义就直接调用了, # 这样固然不符合语法,必定会报错的 print("--->:", request.method) if request.method == "POST": name = request.POST.get("username") pwd = request.POST.get("password") # pwd = request.POST["password"] print(request.POST) print(name, pwd) # 这里的数据判断应该是从数据库里面取出数据来进行对比的,设计到mysql的操做 conn = pymysql.connect( host="localhost", user="root", database="book_list", password="123", ) cur = conn.cursor() sql = "select name, pwd from userinfo ;" cur.execute(sql) ret = cur.fetchall() print(ret) for i in ret: if i[0] == name and i[1] == pwd: return redirect("http://www.luffycity.com") else: error_msg = "you've gotten wrong msg" return render(request, "index.html", {"error": error_msg}) def class_list(request): # conn = pymysql.connect( # host="localhost", # user="root", # password="123", # database="book_list", # charset="utf8") # cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # sql="select id,name from class order by id;" # cursor.execute(sql) # ret = cursor.fetchall() # cursor.close() # conn.close() # print(ret) # return render(request, "class_list.html",{"class_list":ret}) return render(request, "class_list.html") def hm_btst(request): print(request.method) error_msg = "" if request.method == "POST": print(request.POST) name = request.POST.get("name") pwd = request.POST.get("pwd") print(request.POST) print(name, pwd) # 去到数据库里面作校验 conn = pymysql.connect( host="localhost", user="root", database="book_list", password="123", ) cur = conn.cursor() sql = "select name,pwd from userinfo;" cur.execute(sql) ret = cur.fetchmany(4) for i in ret: if i[0] == name and i[1] == pwd: return redirect("https://www.sogo.com") else: error_msg = "you've gotten wrong msg" return render(request, "hm-bootstrap.html", {"error": error_msg}) # 这里的参数是一个包裹着大量的请求相关的参数,全部跟请求相关的数据都会包裹在这里, # 而error是咱们写在页面上的那个硬塞入的p标签包裹着的数据,它做为一个key存入字典, # 它对应的value就是这里咱们在函数里面定义的error_msg这个变量 return render(request, "hm-bootstrap.html") # 展现全部的班级列表 def class_form(request): # 这个函数是展现全部的班级列表 # 1.去数据库里面取出数据 conn = pymysql.connect( host="localhost", user="root", password="123", database="book_list", charset="utf8") # 指定输出的结果类型是字典这里的DictCursor是django里面自带的封装好的功能, # 咱们把它记下来而后用的时候想到它就能够完成咱们须要的工做 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # cursor=conn.cursor() # 这样写就是获得元祖的结果, # 咱们须要把它转换成字典,而后咱们才能经过字典的特性键对值的方式去取值 sql = "select id,cname from class order by id;" cursor.execute(sql) ret = cursor.fetchall() cursor.close() conn.close() print(ret) # 2 用数据去填充HTML页面 这里须要去看视频理解一下---->已经理解过了 # 这里是key和value的方式,{key:value},class_form是变量名, # 咱们这里写的变量名class_form须要和HTML里面的for i in class_form对应上, # 这两个是必需要保持一致的,后面的ret是咱们上面mysql语句运行以后的获得的结果赋值给这个变量了 return render(request, 'class-form.html', {"class_form": ret}) # , {"class-form": ret}这里的变量命名不够规范因此会报错 # 添加班级 def add_class(request): if request.method == "POST": class_name = request.POST.get("cname") # 由于咱们的id是自增的因此咱们在这里只须要增长cname就行了,只须要定义这一个变量就够了 # 1.去数据库里面取出数据 conn = pymysql.connect( host="localhost", user="root", password="123", database="book_list", charset="utf8") # 指定输出的结果类型是字典这里的DictCursor是django里面自带的封装好的功能, # 咱们把它记下来而后用的时候想到它就能够完成咱们须要的工做 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "insert into class (cname) VALUES (%s);" cursor.execute(sql, class_name) conn.commit() # 增长操做,咱们须要有提交动做,由于对数据库进行了修改 cursor.close() conn.close() return redirect("/class_form/") return render(request, 'add-class.html') # 删除课程 def delete_class(request): # 根据班级id删除 # 班级id从数据库里面取出来 print(request.GET) class_id = request.GET.get("class_id") print(class_id) # 去到数据库里面删除 conn = pymysql.connect( host="localhost", user="root", password="123", database="book_list", charset="utf8") cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "delete from class where id=%s;" cursor.execute(sql, class_id) conn.commit() # 对数据库进行改变须要提交操做 cursor.close() conn.close() # return HttpResponse(class_id) return redirect('/class_form/') # 修改课程 def edit_class(request): if request.method == "POST": class_id = request.POST.get("id") class_name = request.POST.get("cname") # 去数据库里面更新 conn = pymysql.connect( host="localhost", user="root", password="123", database="book_list", charset="utf8") cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "update class set cname=%s where id=%s;" cursor.execute(sql, (class_name, class_id)) conn.commit() cursor.close() conn.close() return redirect('/class_form/') # 取到被编辑的班级id class_id = request.GET.get("class_id") # 去数据库里面查询当前班级的信息 conn = pymysql.connect( host="localhost", user="root", password="123", database="book_list", charset="utf8") cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "select id,cname from class where id=%s;" cursor.execute(sql, class_id) ret = cursor.fetchone() cursor.close() conn.close() print(ret) return render(request, "edit-class.html", {"class_info": ret}) # 做业开始写, # 展现全部的讲师列表 def teacher_form(request): # 去到数据库里面取出数据 conn = pymysql.connect( host="localhost", user="root", password="123", database="book_list", charset="utf8") # 把获得是数据以字典的形式展现出来 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 写sql语句 sql = "select id, tname from teacher order by id;" cursor.execute(sql) ret = cursor.fetchall() cursor.close() conn.close() print(ret) return render(request, "teacher-form.html", {"teacher_form": ret}) def add_teacher(request): if request.method == "POST": teacher_name = request.POST.get("tname") conn = pymysql.connect( host="localhost", user="root", password="123", database="book_list", charset="utf8") # 把获得是数据以字典的形式展现出来这里的DictCursor是django里面包裹的封装好的语法,直接用便可 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "insert into teacher (tname) VALUES (%s);" cursor.execute(sql, teacher_name) conn.commit() cursor.close() conn.close() return redirect("/teacher_form/") return render(request, "add-teacher.html") def edit_teacher(request): if request.method == "POST": teacher_id = request.POST.get("id") teacher_name = request.POST.get("tname") conn = pymysql.connect( host="localhost", user="root", password="123", database="book_list", charset="utf8") cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "update teacher set tname=%s where id=%s;" cursor.execute(sql, (teacher_name, teacher_id)) res = cursor.fetchone() conn.commit() cursor.close() conn.close() return redirect("/teacher_form/") # 这里咱们把数据更新以后就回到了咱们的展现表格的页面,可是返回以后须要获得把数据替换掉以后的结果,这里的代码是没有办法去是现这一步的 # 因此咱们须要接着去写代码实现接下来的功能, # 去拿到被编辑的teacher的id teacher_id = request.GET.get("teacher_id") # 去数据库里面查询当前讲师的信息 conn = pymysql.connect( host="localhost", user="root", password="123", database="book_list", charset="utf8") cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "select id, tname from teacher where id=%s;" cursor.execute(sql, teacher_id) res = cursor.fetchone() # 这里咱们虽然是把fetchone改为了fetchall,看起来反正个人sql语句是获得一个结果根据个人语法是这样的,若是是在sql里面的话结果是同样的 # 可是咱们的程序是没法识别的,它只能知道你的fetchall就是获得多个结果,它只能看到你的fetchall,并不能根据fetchall倒推出你的sql语句是获得的一个结果而不是多个,因此咱们不可以改为fetchall去写 # 咱们的fetchall系统识别到它是获得多个结果的,因此它没法肯定把哪一个结果给你放到输入框里面显示出来,因此就直接选择的简单粗暴的方式不去显示了,这就是它的解决方案,因此你看,咱们的计算机甚至都不会拐弯,它一点都不够智能, # 因此咱们必需要了解每个环节是什么意思,甚至咱们的每个变量都须要咱们去理解为何这里须要使用它而不是它,否则本身随便乱改就不会获得预期的效果,这是无可厚非的, # 若是执意要改的话,咱们只可以花掉更多的时间去一点点找到错处而后去调试,直至你完全理解了那些细节, cursor.close() conn.close() print(res) return render(request, "edit-teacher.html", {"teacher_info": res}) def delete_teacher(request): # 根据老师id删除 # 讲师id从数据库里面取出来 print(request.GET) teacher_id = request.GET.get("teacher_id") print(teacher_id) # 去到数据库里面删除 conn = pymysql.connect( host="localhost", user="root", password="123", database="book_list", charset="utf8") cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "delete from teacher where id=%s;" # 咱们这里的%s是占位符,这里的占位符是为了动态传参, # 咱们的程序不可以写死了,须要灵活,须要足够的包容性,因此须要在这里写上一个占位符,可是咱们的sql语句这样一来就不够完整了, # 因此在执行的时候须要把占位符里面的缺失的那一块补齐,这样才可以拼凑出完整的sql语句, # 然而咱们补齐的那部分就是咱们上面定义的变量,那个变量的做用是存放咱们取出想要的数据用的, cursor.execute(sql, teacher_id) conn.commit() # 对数据库进行改变须要提交操做 cursor.close() conn.close() # return HttpResponse(class_id) return redirect("/teacher_form/")
咱们的django项目刚刚建立的时候须要创建几个文件件,
templates------>用于咱们存放全部的HTML页面,它自己就是一个文件夹,在pycharm里面咱们的文件夹是directory,
static-------->用于存放咱们全部的静态文件,它本省也是一个文件夹,也是directory的格式
tool----------->用于存放咱们本身写好的一些模块,也就是一些py文件,咱们的不少复用性高的功能代码都是须要封装到一个函数里面而后存放于一个单独的文件中,实现功能解耦,因此它必须是一个包,咱们的包和文件的区别就是一个有init文件一个没有,所谓的init就是__init__.py 它就是用于区分包和文件的关键点,咱们的包建立之初的时候就会有这个文件,它的存在就是让咱们的pycharm识别出来他是一个包而不是一个文件夹,那么咱们的包就是python Package,咱们想要包的时候就使用这个格式去创建
要想让他跑起来须要配合相应的html文件:
相应的html文档:
展现class_form列表:
<!DOCTYPE html> <!-- saved from url=(0042)https://v3.bootcss.com/examples/dashboard/ --> <html lang="zh-CN"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其余内容都*必须*跟随其后! --> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.min.css"> <title>表格面板</title> <!-- Bootstrap core CSS --> {# <link href="./Dashboard_files/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet">#} <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7/css/bootstrap.min.css"> <!-- Custom styles for this template --> {# <link href="./Dashboard_files/dashboard.css" rel="stylesheet">#} <link rel="stylesheet" href="/static/css/dashboard.css"> <!-- Just for debugging purposes. Don't actually copy these 2 lines! --> <script src="static/ie-emulation-modes-warning.js"></script> <style> td > button { align-content: center; } </style> <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script> <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> </head> <body> <!--模态框开始--> <div class="modal fade" tabindex="-1" role="dialog" id="myModal"> <!--模态框必需要是body的直系子标签才生效不然会报错--> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> <h4 class="modal-title">晓风干,泪痕残</h4> </div> <!--模态框的主体开始--> <div class="modal-body"> <form class="form-horizontal"> <div class="form-group"> <label for="inputName" class="col-sm-2 control-label">姓名</label> <div class="col-sm-10"> <input type="text" class="form-control" id="inputName" placeholder="Name"> </div> </div> <div class="form-group"> <label for="inputEmail" class="col-sm-2 control-label">邮箱</label> <div class="col-sm-10"> <input type="email" class="form-control" id="inputEmail" placeholder="Email"> </div> </div> <div class="form-group"> <label for="inputHabit" class="col-sm-2 control-label">爱好</label> <div class="col-sm-10"> <input type="text" class="form-control" id="inputHabit" placeholder="Habit"> </div> </div> </form> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> <!-- 模态框主体结束 --> </div><!-- /.modal-dialog --> </div> </div> <!--模态框结束--> <!--页面的头部--> <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container-fluid"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="https://v3.bootcss.com/examples/dashboard/#hm-2表格面板.html">Project name</a> </div> <div id="navbar" class="navbar-collapse collapse"> <ul class="nav navbar-nav navbar-right"> <li><a href="https://v3.bootcss.com/examples/dashboard/#hm-2表格面板.html">Dashboard</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/#hm-2表格面板.html">Settings</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/#hm-2表格面板.html">Profile</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/#hm-2表格面板.html">Help</a></li> </ul> <form class="navbar-form navbar-right"> <input type="text" class="form-control" placeholder="Search..."> </form> </div> </div> </nav> <!--页面的头部--> <div class="container-fluid"> <div class="row"> <!--页面的左边开始--> <div class="col-sm-3 col-md-2 sidebar"> <div> <ul class="nav nav-sidebar"> <li class="active"><a href="https://v3.bootcss.com/examples/dashboard/#hm-2表格面板.html">Overview <span class="sr-only">(current)</span></a> </li> <li><a href="https://v3.bootcss.com/examples/dashboard/#hm-2表格面板.html">Reports</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/#hm-2表格面板.html">Analytics</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/#hm-2表格面板.html">Export</a></li> </ul> </div> <ul class="nav nav-sidebar"> <li><a href="https://v3.bootcss.com/examples/dashboard/hm-2表格面板.html">Nav item</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/hm-2表格面板.html">Nav item again</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/hm-2表格面板.html">One more nav</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/hm-2表格面板.html">Another nav item</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/hm-2表格面板.html">More navigation</a></li> </ul> <ul class="nav nav-sidebar"> <li><a href="https://v3.bootcss.com/examples/dashboard/hm-2表格面板.html">Nav item again</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/hm-2表格面板.html">One more nav</a></li> <li><a href="https://v3.bootcss.com/examples/dashboard/hm-2表格面板.html">Another nav item</a></li> </ul> </div> <!--页面的左边结束--> <!--这里开始是咱们须要作的事,表格的右边--> <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main"> <div class="panel panel-default"> <!--default panel contents--> <div class="my-panel-head"> <div class="my-title">Panel heading</div> </div> <!--搜索框和添加框开始--> <div class="row"> <!--咱们要在这个搜索框里面加上form表单而后class要设定为form-inline--> <form class="form-inline"> <div class="form-group" style="padding-left: 16px;"> <label class="sr-only" for="table-search">table search</label> <input type="text" class="form-control" id="table-search" placeholder="search"> </div> <button type="submit" class="btn btn-primary">搜索</button> <button type="button" class="btn btn-success" data-toggle="modal" style="margin-left:640px;" data-target="#myModal">添加 </button> <a href="/add_class/" style="margin-right: 20px;" type="button" class="btn btn-info pull-right">新页面添加</a> </form> </div> <!--搜索框和添加框结束--> <!--主体表格开始--> <div class="my-table-wrapper"> <table style="margin-bottom: 0" class="table table-striped table-bordered"> <thead> <tr> <th>#</th> <th>课程id</th> <th>课程名</th> <th>操做</th> </tr> </thead> <tbody> {% for class in class_form %} {# 这里是for i in 变量名,咱们的class_form是变量名因此须要符合变量命名的规范,数字字母下划线,不能以数字开头,#} {# 咱们在views里面写的函数里须要有返回值咱们返回值里面是本身定义的一个字典,#} {# key就是咱们在这个for循环里面定义的这个变量,这个class_form就是咱们的views里面的函数的返回值里面的键对值里面的key,#} {# 而key对应的value则是本身定义mysql语句执行以后获得的结果赋值给到的那个变量,#} <tr> <td>{{ forloop.counter }}</td> <td scope="row">{{ class.id }}</td> <td>{{ class.cname }}</td> <td class="text-center"> <a href="/edit_class/?class_id={{ class.id }}" type="button" class="btn btn-sm btn-info" aria-label="Left Align"> <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>新页面编辑 </a> <a type="button" class="btn btn-sm btn-success" aria-label="Left Align"> <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>编辑 </a> <a href="/delete_class/?class_id={{ class.id }}" type="button" class="btn btn-sm btn-danger" aria-label="Left Align"> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>删除 </a> </td> </tr> {% endfor %} </tbody> </table> <!--分页开始--> <div class="row" style="margin-right: -25px;margin-left: -35px;"> <div class="col-md-7 col-xs-12 pull-right"> <nav aria-label="Page navigation" style="padding-top:2px; padding-right:10px;float:right;"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <li><a href="#">1</a></li> <li><a href="#">2</a></li> <li><a href="#">3</a></li> <li><a href="#">4</a></li> <li><a href="#">5</a></li> <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> </div> </div> <!--分页结束--> </div> <!--主体表格结束--> </div> </div> </div> </div> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script src="static/js/jquery-3.2.1.min.js"></script> <script src="static/plugins/bootstrap-3.3.7/js/bootstrap.min.js"></script> <script> {# $(document).ready(function(){#} {# $(".my-menu-item").on("click", "a",function () {#} {# #} {# })#} {# })#} </script> </body> </html>
展现列表需用使用到的css文件以及bootstrap文件(在网上能够搜索cdn,在标签中引入连接便可,这样比较方便,节省硬盘空间)
编辑列表:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>change-class</title> </head> <body> <form action="/edit_class/" method="post"> <input type="text" name="id" value="{{ class_info.id }}"> <input type="text" name="cname" value="{{ class_info.cname }}"> <input type="submit" value="put in"> </form> </body> </html>
增长列表:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>add-class</title> </head> <body> <form action="/add_class/" method="post"> <input type="text" name="cname" placeholder="课程名字"> {# <input type="text" name="id" placeholder="课程id">#} {# 咱们表格设计的时候id设置成为了自增,#} {#因此咱们不须要本身增长它,若遇到其余的字段值,咱们是能够继续在这里接着写input框的#} <input type="submit" value="put in"> </form> </body> </html>
不行,咱们把django搭建起来以后还用到了pymysql的内容,咱们的数据库须要搭建好才能够,不然是没法使用的,
简单写几句吧,关于咱们建库建表的命令行,
mysql,(我是把个人mysql文件都配置好了,因此直接在cmd里面就可以直接输入这一行进入数据库里面进行操做)
show databases;
create database book_list;(这里咱们把这个库创建好,由于咱们用到的pymysq须要使用这个库,
use book_list;查看库
show tables;查看库里的表格
CREATE TABLE class(
id INT AUTO_INCREMENT PRIMARY KEY ,
cname CHAR(20) NOT NULL UNIQUE
)ENGINE =innodb DEFAULT CHARSET="utf8"; 库已经创建好了,而后在里面插入一些表格,
INSERT INTO class (cname) VALUES ("jumping"),
("java"),("web"),("biology"),("math"),
("python"),("linnux"); # 这里是在表格中插入一些数据
先让django项目起来,点击绿色的那个三角按钮便可,这样咱们就能在项目起来以后的那个网页里输入咱们定义好的那些函数的名字所对应的url域名网址,在url里面咱们有设置网址的输入内容.
全部的文件咱们都配置好了,按照使用规则去运行他们便可了,
http://www.cnblogs.com/liwenzhou/p/8258992.html
咱们能够这样理解:全部的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。
这样咱们就能够本身实现Web框架了。
import socket sk = socket.socket() sk.bind(("127.0.0.1", 80)) sk.listen(5) while True: conn, addr = sk.accept() data = conn.recv(8096) conn.send(b"OK") conn.close()
web的框架是上面的客户端和服务端,这就是本质的东西
因此,必须有一个统一的规则,让你们发送消息、接收消息的时候有个格式依据,不能随便写。
这个规则就是HTTP协议,之后浏览器发送请求信息也好,服务器回复响应信息也罢,都要按照这个规则来。
HTTP协议主要规定了客户端和服务器之间的通讯格式,那HTTP协议是怎么规定消息格式的呢?
让咱们首先看下咱们在服务端接收到的消息是什么。
而后再看下咱们浏览器收到的响应信息是什么。
响应头在浏览器的network窗口能够看到,咱们看到的HTML页面内容就是响应体。本质上仍是字符串,由于浏览器认识HTML,因此才会渲染出页面。
每一个HTTP请求和响应都遵循相同的格式,一个HTTP包含Header和Body两部分,其中Body是可选的。 HTTP响应的Header中有一个 Content-Type
代表响应的内容格式。如 text/html
表示HTML网页。
HTTP GET请求的格式:
GET /path HTTP/1.1 header1:v1\r\n header2:v2\r\n
使用 \r\n
分隔多个header
HTTP POST请求格式:
POST /path HTTP/1.1 header1:v1\r\n header2:v2\r\n \r\n\r\n 请求体...
当遇到连续两个 \r\n\r\n
时,表示Header部分结束了,后面的数据是Body。
HTTP响应的格式:
200 OK Header1:v1\r\n Header2:v2\r\n \r\n\r\n 响应体...
让咱们的Web框架在给客户端回复响应的时候按照HTTP协议的规则加上响应头,这样咱们就实现了一个正经的Web框架了。
这样,服务器程序就须要为不一样的框架提供不一样的支持。这样混乱的局面不管对于服务器仍是框架,都是很差的。对服务器来讲,须要支持各类不一样框架,对框架来讲,只有支持它的服务器才能被开发出的应用使用。
这时候,标准化就变得尤其重要。咱们能够设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就能够配合使用。一旦标准肯定,双方各自实现。这样,服务器能够支持更多支持标准的框架,框架也可使用更多支持标准的服务器。
WSGI(Web Server Gateway Interface)就是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。
经常使用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来作服务器。
无论是什么内容,最后都是转换成字节数据发送出去的。 我能够打开HTML文件,读取出它内部的二进制数据,而后发送给浏览器。
咱们经过了socket链接就打开了一个HTML文件,
from wsgiref.simple_server import make_server def index(): with open("index.html", "rb") as f: data = f.read() return [data, ] def home(): with open("home.html", "rb") as f: data = f.read() return [data, ] # 定义一个url和函数的对应关系 URL_LIST = [ ("/index/", index), ("/home/", home), ] def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 url = environ['PATH_INFO'] # 取到用户输入的url func = None # 将要执行的函数 for i in URL_LIST: if i[0] == url: func = i[1] # 去以前定义好的url列表里找url应该执行的函数 break if func: # 若是能找到要执行的函数 return func() # 返回函数的执行结果 else: return [bytes("404没有该页面", encoding="utf8"), ] if __name__ == '__main__': httpd = make_server('', 8000, run_server) print("Serving HTTP on port 8000...") httpd.serve_forever()
这是一个简单的动态,我彻底能够从数据库中查询数据,而后去替换我html中的对应内容,而后再发送给浏览器完成渲染。 这个过程就至关于HTML模板渲染数据。 本质上就是HTML内容中利用一些特殊的符号来替换要展现的数据。 我这里用的特殊符号是我定义的,其实模板渲染有个现成的工具: jinja2
from wsgiref.simple_server import make_server from jinja2 import Template def index(): with open("index2.html", "r") as f: data = f.read() template = Template(data) # 生成模板文件 ret = template.render({"name": "Alex", "hobby_list": ["烫头", "泡吧"]}) # 把数据填充到模板里面 return [bytes(ret, encoding="utf8"), ] def home(): with open("home.html", "rb") as f: data = f.read() return [data, ] # 定义一个url和函数的对应关系 URL_LIST = [ ("/index/", index), ("/home/", home), ] def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 url = environ['PATH_INFO'] # 取到用户输入的url func = None # 将要执行的函数 for i in URL_LIST: if i[0] == url: func = i[1] # 去以前定义好的url列表里找url应该执行的函数 break if func: # 若是能找到要执行的函数 return func() # 返回函数的执行结果 else: return [bytes("404没有该页面", encoding="utf8"), ] if __name__ == '__main__': httpd = make_server('', 8000, run_server) print("Serving HTTP on port 8000...") httpd.serve_forever()
咱们先安装上django
而后了解它的工做原理,
而后掌握它的一些用法,
最后使用它实现一些简单的小功能
pip3 install django==1.11.9
下面的命令建立了一个名为"mysite"的Django 项目:
django-admin startproject mysite
或者使用pycharm直接就能够建立,反而更加简单:
找到pycharm里面左上角的file--->new project--->django--->create 就能够获得一个django项目了,注意,咱们在点击create的时候须要选择open in new window,这样就是给新建立的django项目开启新的窗口,django项目必需要开新的窗口而后才能够运行,不然是执行不成功的,
from django.shortcuts import HttpResponse, render, redirect
内部传入一个字符串参数,返回给浏览器。它是负责响应浏览器的数据
例如:
def index(request): # 业务逻辑代码 return HttpResponse("OK") # 这的括号里面的内容就是咱们须要返回给浏览器的东西,能够随意设置的,只要是字符串就行
除request参数外还接受一个待渲染的模板文件和一个保存具体数据的字典参数。
将数据填充进模板文件,最后把结果返回给浏览器。(相似于咱们上面用到的jinja2)
它至关于咱们把一个文件里面的数据读取出来而后返回给一个函数的这样的操做
相似于
def login():
with open("login.html", encoding="utf8") as fh:
dat = fh.read()
time_str = str(time.time())
print(time_str)
new_dat = dat.replace("#$101$#", time_str)
return new_dat
这里的操做就是render的用法,若是咱们不适用render的话,咱们须要使用一个函数去
打开一个文件,而后把文件读出来,使用其余的字符串去替换它,而后把替换的结果返回给函数,
这里的打开文件-读取文件-替换文件-返回给函数这一系列的过程都是render它内部的封装的功能,只要引用它,咱们均可以实现这些功能,
节省代码.
例如:
def index(request): # 业务逻辑代码 return render(request, "index.html", {"name": "alex", "hobby": ["烫头", "泡吧"]})
接受一个URL参数,表示跳转到指定的URL。(就是超连接咱们从一个链接按钮跳转到另外一个链接地址) # 这里就相似于咱们的HTML标签里面的一个a标签,它里面就有一个href这个属性,这个属性就是负责承接跳转的功能,咱们的redirect就是跟他同样的,他后面的参数写什么,就往那个地址去跳转
例如:
def index(request): # 业务逻辑代码 return redirect("/home/")
全部跟请求相关的操做都是封装到这个参数里面的
mysite/
manage.py # 管理文件
mysite # 项目目录
__init__.py
setting.py # 配置
urls.py # 路由--> url和函数的对应关系
wsgi.py # runserver命令就使用wsgiref模块作简单的web server
配置文件:
咱们的django建立以后须要把一些内部的文件进行设置,设置好了以后才能够投入使用,须要设置的地方有:
TEMPLATES = [ # 这里咱们是存放html文件的,全部项目里须要用到的HTML文件都放到这里来
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "template")], # template文件夹位置这里是须要本身加上的,若是没有的话
'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',
],
},
},
]
还有须要设置的地方:
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',
]
静态文件配置:(所谓的静态文件就是咱们的css文件和js文件,以及bootstrap文档里面的都是静态文件)
STATIC_URL = '/static/' # HTML中使用的静态文件夹前缀 [咱们的静态文件在django中使用的时候,在引用的时候好比link标签里面的href咱们会先写上这里的静态文件夹前缀,而后从这个静态文件夹前缀里去找其余的文件] STATICFILES_DIRS = [ #这里的位置是咱们本身加上去的,从这里开始都是咱们本身写的,咱们的静态文件都是须要在这里指定位置,而后用的时候好方便从这开始朝起
os.path.join(BASE_DIR, "static"), # 静态文件存放位置 ]
刚开始学习时可在配置文件中暂时禁用csrf中间件,方便表单提交测试。
数据库配置:
咱们把参数设置好了以后还须要在咱们的项目里面的init文件里面把咱们的配置给改一下
import pymysql pymysql.install_as_MySQLdb()
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'book_list', 数据库名 'USER': 'root', 'PASSWORD': '123', 'HOST': '127.0.0.1', 'PORT': '3306', } }
1 python manage.py inspectdb 2 # This is an auto-generated Django model module. 3 # You'll have to do the following manually to clean this up 4 : 5 # * Rearrange models' order 6 # * Make sure each model has one field with primary_key=T 7 rue 8 # * Make sure each ForeignKey has `on_delete` set to the 9 desired behavior. 10 # * Remove `managed = False` lines if you wish to allow D 11 jango to create, modify, and delete the table 12 # Feel free to rename the models, but don't rename db_table 13 values or field names. 14 from __future__ import unicode_literals 15 16 from django.db import models 17 18 19 20 21 ================================================================================== 22 这里把咱们在setting里面配置好的数据库里面的全部的表都生成code 23 code_first 24 25 26 class BkL(models.Model): 27 name = models.CharField(max_length=200) 28 author = models.CharField(max_length=255, blank=True, n 29 ull=True) 30 thickness = models.CharField(max_length=255) 31 how_like = models.CharField(max_length=255) 32 33 class Meta: 34 managed = False 35 db_table = 'bk_l' 36 37 38 class Class(models.Model): 39 cname = models.CharField(unique=True, max_length=20) 40 41 class Meta: 42 managed = False 43 db_table = 'class' 44 45 46 class Class2Teacher(models.Model): 47 tid = models.ForeignKey('Teacher', models.DO_NOTHING, d 48 b_column='tid', blank=True, null=True) 49 cid = models.ForeignKey(Class, models.DO_NOTHING, db_co 50 lumn='cid', blank=True, null=True) 51 52 class Meta: 53 managed = False 54 db_table = 'class_2_teacher' 55 56 57 class Dep(models.Model): 58 id = models.IntegerField(blank=True, null=True) 59 name = models.CharField(max_length=20, blank=True, null 60 =True) 61 62 class Meta: 63 managed = False 64 db_table = 'dep' 65 66 67 class Em(models.Model): 68 id = models.AutoField(unique=True) 69 name = models.CharField(max_length=20) 70 sex = models.CharField(max_length=6) 71 age = models.IntegerField() 72 hire_date = models.DateField() 73 post = models.CharField(max_length=50, blank=True, null 74 =True) 75 post_comment = models.CharField(max_length=100, blank=T 76 rue, null=True) 77 salary = models.FloatField(blank=True, null=True) 78 office = models.IntegerField(blank=True, null=True) 79 depart_id = models.IntegerField(blank=True, null=True) 80 81 class Meta: 82 managed = False 83 db_table = 'em' 84 85 86 class Loginuser(models.Model): 87 name = models.CharField(max_length=32, blank=True, null 88 =True) 89 pwd = models.CharField(max_length=32, blank=True, null= 90 True) 91 extra = models.CharField(max_length=32, blank=True, nul 92 l=True) 93 94 class Meta: 95 managed = False 96 db_table = 'loginuser' 97 98 99 class Student(models.Model): 100 sname = models.CharField(unique=True, max_length=20) 101 cid = models.ForeignKey(Class, models.DO_NOTHING, db_co 102 lumn='cid', blank=True, null=True) 103 104 class Meta: 105 managed = False 106 db_table = 'student' 107 108 109 class Teacher(models.Model): 110 tname = models.CharField(unique=True, max_length=20) 111 112 class Meta: 113 managed = False 114 db_table = 'teacher' 115 116 117 class Userinfo(models.Model): 118 pwd = models.CharField(max_length=10) 119 name = models.CharField(max_length=10) 120 121 class Meta: 122 managed = False 123 db_table = 'userinfo' 124 125 126 class Users(models.Model): 127 id = models.IntegerField(primary_key=True) 128 name = models.CharField(max_length=30) 129 age = models.IntegerField(blank=True, null=True) 130 131 class Meta: 132 managed = False 133 db_table = 'users' 134 135 136 class Whatever(models.Model): 137 name = models.CharField(unique=True, max_length=10) 138 age = models.IntegerField() 139 140 class Meta: 141 managed = False 142 db_table = 'whatever'