day 61 Django part-1 django的安装,以及初学者三件套(以及settings中的mysql配置)

 

 

我们的django到底是什么东西呢?

我们的代码都是在后台写的,包括我们的pycharm都是属于后台的工具,但是我们的后端开发说到底是需要开发完了之后拿到用户面前的,让我们的用户看到我们的东西,首先要让他们看到,然后才能够在看到的基础上来进行一些交互,然后大体的框架就算是搭建成功了,再接下来就是细节的填充,以及功能的扩展,根据业务的发展以及用户的需求去满足,一一实现需求.

上面说了一通的废话,我们的django到底跟这一切又有什么关系呢?

我们的代码是后端的东西,它如果放到用户的眼前是需要一些过程的,我们的前端是可以让我们的用户直观的看到效果,我们的前端改动一些标签就可以让用户明显感受到差异,所以我们的前端是跟用户交互更加直接的,但是前端的功能都是一些浮于表面的东西,它是作为装饰的,很多的功能仅仅靠前端是无法实现的,需要后端来进行功能的主要开发,然后前端再在后端的基础上进行页面的渲染,实现用户的交互,那么我们的前端就需要跟后端关联上,要怎么实现关联上的同时还能不出错的无缝衔接上稳定地投入使用呢?,这个时候就需要我们的django了,它就是让我们的前端和后端无缝衔接上的同时,稳定地投入使用,我们的web框架就是干这个事情的,下面我们会提到web框架的本质,它最根本的就是socket套接字通信,我们开启一个服务端然后它就能够永远稳定地运行下去,接下来我们的客户端配好了端口和ip地址的时候就能够连接上它,我们的django就封装的有这个socket套接字功能,它本身就自带套接字通信功能,所以,你看我们需要用到的东西在这个django里面统统都会实现,它很牛逼吧,什么都是自带的,然而它还不仅仅是这样,它的功能远远比我们想象得的要强大得多,暂且就理解它为一个封装了超多功能的异常庞大的模块吧,我们要实现前后端的交互它是少不了的.

它里面有超多的封装好的模块.我们只需要在使用的时候把它想起来然后就跟我们引入模块或者引入文件的时候一样使用import 就可以引入到你的代码块里面进行使用了

 

 

它核心的三件套是必须要掌握的,一切的功能都是基于这三者来实现的,

Httpresponse,--负责来响应浏览器的,需要浏览器返回什么就在它里面定义什么即可,浏览器的根本就是返回字符串,所以Httpresponse("str(ok)")这样写就可以

render, --负责接收request参数,然后还有一个渲染的页面(也就是一个HTML标签),以及保存数据用的一个字典数据类型的参数.这个render主要的功能就是渲染页面,在渲染的同时我们需要把一些参数填充到所渲染的页面里面去,就需要用到这个render功能,[那我们什么时候需要使用到参数去填充页面的情况呢,我们的页面是提前写好的,那是前端的时候,现在我们需要跟后端进行一些交互,这个时候前端显示的数据就会有所调整,根据特殊的要求来进行调整,这个时候我们的代码就需要后端来实现了,把后端改好的代码填充到前端去,就需要把前端的页面设置一块地方用来预存参数,当我的后端需要改变功能的时候可以启动到前端预存的那些参数然后进行修改,这个时候就需要使用到填充参数到所渲染的页面中去]

redirect,--负责跳转页面,后端的代码块码完之后我们想让页面往何处跳转就使用它去跳转,return redirect("/sogo/") 这里就是跳转的页面,之所以这样写,是因为我们的url域名里面都是这样的格式,https://i.cnblogs.com/EditPosts.aspx?postid=8269914,例如这里的http后面的域名就是这样的格式,

这里还有一个很重要的点就是request,它是一个参数,是我们在django里面写函数的时候需要传入的参数,这个参数是干什么用的呢,它里面包裹了大量的信息,都是关于请求的数据信息,

所有跟请求相关的数据都是由它来进行接收,我们的形参就是用来接收各种的参数的,它就是那样的一个形参,它只是接收跟请求相关的参数,我们以后会学到它的大量的用法,包括都有哪些是跟请求相关的,请求都是有哪些,等等.

 

 老师的笔记:

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. 登录失败就返回当前页面


    
View Code

 

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请求传数据:
        是放在请求体里面的
        

        













    
        
        
View Code

 

 创建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")
]
View Code

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),
]
View Code

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/")
View Code

我们的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">&times;</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">&laquo;</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">&raquo;</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>
View Code

 

展示列表需用使用到的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>
View Code

增加列表:

<!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>
View Code

不行,我们把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()
View Code

web的框架是上面的客户端和服务端,这就是本质的东西

所以,必须有一个统一的规则,让大家发送消息、接收消息的时候有个格式依据,不能随便写。

这个规则就是HTTP协议,以后浏览器发送请求信息也好,服务器回复响应信息也罢,都要按照这个规则来。

HTTP协议主要规定了客户端和服务器之间的通信格式,那HTTP协议是怎么规定消息格式的呢?

让我们首先看下我们在服务端接收到的消息是什么。

 

然后再看下我们浏览器收到的响应信息是什么。

响应头在浏览器的network窗口可以看到,我们看到的HTML页面内容就是响应体。本质上还是字符串,因为浏览器认识HTML,所以才会渲染出页面。

HTTP协议介绍

每个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()
View Code

 

这是一个简单的动态,我完全可以从数据库中查询数据,然后去替换我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()
View Code

 

 

我们先安装上django

然后了解它的工作原理,

然后掌握它的一些用法,

最后使用它实现一些简单的小功能

 

安装(安装最新LTS版):

pip3 install django==1.11.9

我们安装的时候可以就在pycharm里面进行就可以,

创建一个django项目:

下面的命令创建了一个名为"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

这三个,是核心内容django里面的核心

HttpResponse

内部传入一个字符串参数,返回给浏览器。它是负责响应浏览器的数据

例如:

def index(request):
    # 业务逻辑代码
    return HttpResponse("OK")  # 这的括号里面的内容就是我们需要返回给浏览器的东西,可以随意设置的,只要是字符串就行

render(渲染)

除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": ["烫头", "泡吧"]})

redirect

接受一个URL参数,表示跳转到指定的URL。(就是超链接我们从一个连接按钮跳转到另一个连接地址)  # 这里就类似于我们的HTML标签里面的一个a标签,它里面就有一个href这个属性,这个属性就是负责承接跳转的功能,我们的redirect就是跟他一样的,他后面的参数写什么,就往那个地址去跳转

例如:

def index(request):
    # 业务逻辑代码
    return redirect("/home/")

 request:(参数)

所有跟请求相关的操作都是封装到这个参数里面的

 

 

目录介绍:

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'
inspectdb

 

博客地址







posted @ 2018-01-11 23:02  dream-子皿  阅读(212)  评论(0编辑  收藏  举报