前言:

Django囊括了 socket + 前端 + Python + 数据库 的知识,先回忆一下TCP和HTTP协议吧!

TCP协议 HTTP协议

1、TCP/HTTP的关系:

(1)浏览器就是 别人写好的socket客户端

(2)http是建立在 TCP连接之上的,其实就是TCP;

(3)区别

客户端和服务端 建立TCP连接之后 只要一方不conn.close就可以一直传输数据;

TCP特性:不断开

 

(4)HTTP 客户端请求1次,服务响应1次就TCP连接就close掉了;

HTTP特性:下次客户端再次向服务端发送请求时,相互不认识了所以HTTP协议短连接、无状态

 

2、http协议:

请求:请求头+请求体   之间     使用两个换行符分割;

响应:响应头+响应体    之间    使用两个换行符分割;注意我们可以看到的 网页就是服务端响应给用户的响应体(本质是一堆字符串)

(1)、post请求和get请求的区别:

(2)、Get是向服务器发获取数据的一种请求,GET请求的请求体里面内容为空 

Get请求的参数会跟在url后进行传递,请求的数据会附在URL之后,以?分割,以&相连。明文出现在URL上 

 <td><a href="/del_class/?nid={{row.id}}">删除学员</a></td>
 <td><a href="/edit_class/?nid={{row.id}}">编辑</a></td>

 

 

(3)、Post是向服务器提交数据的一种请求

 携带的数据在,请求体里;

 

(4)、http特点

(1次HTTP请求+响应之后,套接字就断开了

 所以:HTTP  是 短连接  + 无状态(客户端第2次发请求,服务端就不认识了) 的协议;

 

一、WEB框架的本质

1、WEB框架的本质是建立在TCP协议上, 服务端开启一个socket服务端客户端连接之后;

2、客户端发送http请求(get/post)

3、服务端内部根据不同的URL请求,响应(响应头+响应体)用户不同的模板(html网页本质是发送字符串)

4、1次Http请求+响应之后,TCP连接断开;

5、自定义web框架 

templates

views.py

def foo1(request):
    with open('templates/alex.html','rb') as f:
        data=f.read()
        f.close()
        return [data]

def foo2(request):
    with open('templates/egon.html','rb')as f:
        data=f.read()
        return [data]

def login(request):
    with open('templates/login.html','rb')as f:
        data=f.read()
        return [data]

def auth(request):
    print(request)
    user,pwd=request.get('QUERY_STRING').split("&")
    print(user,pwd)
    _,u=user.split('=') #_,表示占位扔掉
    _,p=pwd.split('=')
    print(u,p)
    if u=='zhanggen' and p=='123':
        return [b'Login Successful ']
    else:
        return [b'User name or password error']
View Code

urls.py

from day52.views import *
URlpattern=(
        ('/alex/',foo1),
        ('/egon/', foo2),
        ('/login/',login),
        ('/auth/',auth),
               )
View Code

程序入口

from wsgiref.simple_server import make_server

#路径分派
# def application(environ,start_response):
#     start_response('200 OK', [('Content-Type', 'text/html')])
#     path=environ.get('PATH_INFO')
#     print(path)
#     if path=='/alex/':
#         with open('alex.html','rb') as  f:
#            data=f.read()
#            return [data]
#
#     elif path=='/egon/':
#         with open('egon.html','rb') as f1:
#             data1=f1.read()
#             return [data1]
#
#     else:
#         return [b'<h1>404</h1>']
#
# t=make_server(' ',8800,application)
# t.serve_forever()

#随着函数数据增多会 难以管理 于是 定义一个 router函数 存放 url和视图函数的对应关系

from day52.views import *

def routers():
    from day52.urls import URlpattern
    return URlpattern


def application(environ,start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    path=environ.get('PATH_INFO')
    print(path)
    urloattern=routers()
    func=None
    for i in urloattern:
        if path==i[0]:
            func=i[1]
            break
    if func:
        return func(environ)
    else:
        return [b'404']
if __name__ == '__main__':
    t=make_server(' ',8800,application)
    t.serve_forever()
View Code

6、总结

简单来说web框架就是 别人搭建好了舞台,我们根据别人搭建的舞台来做自己的表演。

 

二、WEB框架的组成

1. socket服务端(执行 遵循WSGI:Web Server Gateway Interface的模块)

绑定唯一IP+端口,不间断提供服务,用户使用http协议连接服务端之后 执行wsgi模块(遵循wsgi规范的模块) 分割出以\r\n分割的请求头和请求体,交给中间件---》视图.........

2、路由系统:URL -> 函数

 根据不同URL请求,返回不同的模板;

3、模板引擎渲染:(包含在模板中特殊字符 % 特定数据的替换)

把特定数据(例如来自数据库)  根据包含在模板中(HTML网页)定义的特殊字符{{特殊字符}} ,替换组织成特定字符串整体发送给客户端。

 

三、WEB框架模型 和Python 常见web框架介绍

 

1、web框架模型

MVC模型:model、 view 、controller

MTV模型:   model、 templates、  view 、controller 

 

2、Python的web框架

第一类:同时满足1,2,3条件Tornado

第二类:[第三方1],2,3 --> wsgiref -例如Django

第三类: [第三方a],b,[第三方c]  -例如: flask,

 

四、创建Django框架:

1、在CMD创建Django项目

1.0、pip的使用

Docker容器中设置pip源

只要修改容器的PIP_INDEX_URL环境变量即可;

root@714db2ea867e:~/.pyenv/bin# pip config list
:env:.index-url='https://pypi.tuna.tsinghua.edu.cn/simple'
root@714db2ea867e:~/.pyenv/bin# export PIP_INDEX_URL=xxx
root@714db2ea867e:~/.pyenv/bin# pip config list
:env:.index-url='xxx'
root@714db2ea867e:~/.pyenv/bin# 

 pip list 查看已经安装的python第三方包

D:\版本1\cmdb_rbac_arya>pip list
DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in you
r pip.conf under the [list] section) to disable this warning.
alembic (1.0.1)
APScheduler (3.6.0)
asn1crypto (0.24.0)
attrs (18.1.0)
Automat (0.7.0)
backports.functools-lru-cache (1.4)
baidu-aip (2.2.8.0)
bcrypt (3.1.3)
beautifulsoup4 (4.6.0)
blinker (1.4)
boto3 (1.9.104)
botocore (1.12.104)
cachetools (3.1.0)
certifi (2018.4.16)
cffi (1.11.5)
chardet (3.0.4)
click (6.7)
constantly (15.1.0)
construct (2.5.3)
cryptography (2.3)
cssselect (1.0.3)
cx-Oracle (7.0.0)
cycler (0.10.0)
date2cron (0.1dev-r0)
DBUtils (1.2)
Django (1.11.4)
django-apscheduler (0.3.0)
django-ckeditor (5.4.0)
django-haystack (2.8.1)
django-js-asset (1.0.0)
django-redis (3.8.3)
django-redis-sessions (0.6.1)
django-tinymce (2.7.0)
djangorestframework (3.7.3)
docopt (0.6.2)
docutils (0.14)
dwebsocket (0.5.10)
fabric (2.4.0)
Fabric3 (1.14.post1)
Flask (0.12.2)
Flask-Migrate (2.3.0)
Flask-Script (2.0.6)
Flask-Session (0.3.1)
Flask-SQLAlchemy (2.3.2)
framework (0.1.0)
future (0.16.0)
geetest (3.2.1)
gevent (1.4.0)
google-api-core (1.8.0)
google-api-python-client (1.4.1)
google-auth (1.6.3)
google-cloud-core (0.29.1)
google-cloud-dataproc (0.3.1)
google-cloud-logging (1.10.0)
google-cloud-storage (1.14.0)
google-resumable-media (0.3.2)
googleapis-common-protos (1.5.8)
greenlet (0.4.15)
grpcio (1.19.0)
haystack (0.42)
html5lib (1.0.1)
httplib2 (0.12.0)
hyperlink (18.0.0)
idna (2.7)
incremental (17.5.0)
invoke (1.2.0)
IPy (0.83)
itchat (1.2.32)
itsdangerous (0.24)
JayDeBeApi3 (1.3.2)
jieba (0.39)
Jinja2 (2.10)
jmespath (0.9.4)
JPype1 (0.6.3)
kafka-python (1.4.3)
kazoo (2.5.0)
lxml (4.2.4)
Mako (1.0.7)
MarkupSafe (1.0)
matplotlib (2.1.1)
mrjob (0.6.7)
numpy (1.13.3)
oauth2client (4.1.3)
olefile (0.44)
opencv-python (3.4.0.12)
pandas (0.20.0)
paramiko (2.4.2)
parsel (1.5.0)
pefile (2018.8.8)
pexpect (4.6.0)
pika (0.11.2)
Pillow (4.3.0)
pip (9.0.1)
pipreqs (0.4.9)
ply (3.11)
protobuf (3.6.1)
psutil (5.4.8)
ptyprocess (0.6.0)
py4j (0.10.8.1)
pyasn1 (0.4.4)
pyasn1-modules (0.2.2)
pycparser (2.18)
pycryptodome (3.7.2)
pycryptodomex (3.7.2)
PyDispatcher (2.0.5)
PyHamcrest (1.9.0)
PyHDFS (0.2.1)
pykafka (2.8.0)
PyMySQL (0.7.11)
PyNaCl (1.1.2)
pyOpenSSL (18.0.0)
pyparsing (2.2.0)
pypng (0.0.18)
Pypubsub (4.0.0)
PyQRCode (1.2.1)
pysmi (0.3.2)
pysnmp (4.4.6)
python-crontab (2.3.5)
python-dateutil (2.6.1)
python-editor (1.0.3)
python-memcached (1.59)
python-nmap (0.6.1)
python-ptrace (0.9.3)
pyttsx3 (2.7)
pytz (2017.3)
pywin32 (221)
PyYAML (3.13)
queuelib (1.5.0)
redis (2.10.6)
requests (2.21.0)
rsa (4.0)
s3transfer (0.2.0)
scipy (1.2.1)
Scrapy (1.5.1)
seaborn (0.9.0)
selenium (3.7.0)
service-identity (17.0.0)
setuptools (40.8.0)
simplejson (3.13.2)
six (1.11.0)
SQLAlchemy (1.2.12)
tabulate (0.8.2)
timeout-decorator (0.4.1)
tornado (4.5.2)
Tornado-MySQL (0.5.1)
Twisted (18.7.0)
tzlocal (1.5.1)
uritemplate (3.0.0)
urllib3 (1.23)
virtualenv (15.1.0)
w3lib (1.19.0)
webencodings (0.5.1)
Werkzeug (0.13)
wheel (0.30.0)
Whoosh (2.7.4)
winpexpect (1.5)
WTForms (2.2.1)
wxpy (0.3.9.8)
wxPython (4.0.3)
xlrd (1.2.0)
XlsxWriter (1.1.2)
xlwt (1.3.0)
yagmail (0.11.214)
yarg (0.1.9)
zope.interface (4.5.0)

D:\版本1\cmdb_rbac_arya>pip show yagmail
Name: yagmail
Version: 0.11.214
Summary: Yet Another GMAIL client
Home-page: https://github.com/kootenpv/yagmail
Author: Pascal van Kooten
Author-email: kootenpv@gmail.com
License: MIT
Location: d:\python3.6.1\lib\site-packages
Requires:

D:\版本1\cmdb_rbac_arya>
pip list

pip show SomePackeages 查看某些包的信息

:\版本1\cmdb_rbac_arya>pip show yagmail xlwt
Name: yagmail
Version: 0.11.214
Summary: Yet Another GMAIL client
Home-page: https://github.com/kootenpv/yagmail
Author: Pascal van Kooten
Author-email: kootenpv@gmail.com
License: MIT
Location: d:\python3.6.1\lib\site-packages
Requires:
---
Name: xlwt
Version: 1.3.0
Summary: Library to create spreadsheet files compatible with MS Excel 97/2000/XP/2003 XLS files, on any platform, with Python 2.6, 2.7, 3.3+
Home-page: http://www.python-excel.org/
Author: John Machin
Author-email: sjmachin@lexicon.net
License: BSD
Location: d:\python3.6.1\lib\site-packages
Requires:
pip show yagmail xlwt

1.1、pip 安装Django

安装:
pip install django==1.11.7 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

更新:
pip install -U django

卸载:
pip uninstall django

查看版本在cmd/bash
[root@ecdb ~]# python -m django --version
1.11.7

1.2、创建Django程序 django-admin startproject XXX(站点名称)

1.3、进入程序目录:  cd mysite 在 manage.py文件目录下 注意!否则会导致静态文件引用失效!

1.4、创建 app: python manage.py startapp XXX(app名称)

1.5、启动Django项目:  python3 manage.py runserver 127.0.0.1:8080

1.6、后台启动Django项目:nohup python3 manage.py  runserver 0.0.0.0:8001& 

 

2、在Pycharm创建Django项目

左上角file--->NewProject--->

 

 

 

五、Django目录配置

 

1、Django框架包含的文件说明:

seting.py -----Django的配置文件

 

url.py--------路由系统(url和函数的对应关系)

 

wsgi.py-------用于定义该Django程序,用什么socket来实现。wsgirof(测试环境) ,uwsgi(生产环境)


manage.py------对Django程序的所有操作和管理基于该程序例:Python manage.py run server 启动Django程序

 

2.配置

 

 2.1、模板路径配置(html文件存放位置)

在settings.py文件中找到 TEMPLATES 

'DIRS': [os.path.join(BASE_DIR, 'templates')],

 

 2.2、静态文件配置(JS、CSS、img文件存放位置)  !!常用

STATIC_URL = '/zhanggen/'                                  #模板语言 引用静态文件的前缀    

STATICFILES_DIRS=(                                  #静态文件真实目录
os.path.join(BASE_DIR,'static'),
)

 

显示图片

MEDIA_URL="/media/"
MEDIA_ROOT=os.path.join(BASE_DIR,"media")
setings.py
from django.views.static import serve
from django.conf import settings
urlpatterns = [
    url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}),
                    ]
urls.py

 

开始在客户端访问图片:http://127.0.0.1:8000/media/upload/avatar/1.bmp

 

 

 

2.3、关闭CSRF验证中间件(注释)

MIDDLEWARE = [
# 'django.middleware.csrf.CsrfViewMiddleware',
]

 

2.4、使用Django总结:

1、创建project 

2、配置
-------配置模板路径

-------配置静态文件路径

-------配置模板路径

-------关闭CSRF验证中间件

 

 2.5、Django连接MySQL数据库

 

Django项目下__init__.py文件

import pymysql                               #Python2使用的MySQLdb模块,Python3后改成pymysql了
pymysql.install_as_MySQLdb()

Django项目下__setings__.py文件

DATABASES={
'default': {
        'ENGINE':'django.db.backends.mysql',
        'NAME':"s5orm",
        'USER':'root',
        'PASSWORD':'!@c我不高速你',
        'HOST':'192.168.16.14',
        'PORT':'3306'
    }
}

 

六、使用Django

 

1、路由系统

urlpatterns = [url(r'^ URL/',URL对应的处理函数),]  注意^有时候不加也可以,但是有时候会匹配不到URL;

urlpatterns = [url(r'^login/',login),] ---------URL对应的函数

urlpatterns = [
    url(r'^modal/',view.modal),
    url(r'^modal_add/',view.modal_add),
    url(r'^modal_del/',view.modal_del),
    url(r'^modal_edit/',view.modal_edit),
    ]
View Code

 

2、视图函数

FBV

千万不要忘了request参数哦!!

 

request相关:

request对象的属性和方法:客户端请求相关

request.FILES.get('picture2') 获取文件对象

request.method 查看请求方式

request.body   获取所有请求体中携带信息,例如获取json格式数据,data=json.loads(request.body.decode('utf-8'));

request.GET 查看GET请求携带的数据信息

request.POST 查看POST请求携带的数据信息

{'username': ['zhanggen'], 'password': ['123.com']}

request.POST.get("tile")获取GET请求携带信息

request.GET.get("tile")获取POST请求携带信息

request.COOKIES.get('key')获取cokie信息

request.path_info :查看当前访问的url信息(不包含写的的参数)  #arya/cmdb/worker_order/handle/

request.get_full_path():查看当前访问url的信息(包含参数)      #/arya/cmdb/worker_order/?q=zhanggen

 request.get_raw_uri() 查看当前访问url信息(包含所有)             #http://127.0.0.1:8000/arya/cmdb/worker_order/handle/?id=110

request.get_host() 获取当前主机

request.get_port()获取当前Django项目占用端口

request.META.get('REMOTE_ADDR') 获取访问用户的IP地址

request.META.get('HTTP_X_FORWARDED_FOR') 获取用户使用的代理IP

request.META.get('HTTP_REFERER') : 获取上一次访问的url地址;用于页面返回跳转!

(代理IP就是客户端访问到服务端,所经历代理的IP地址;注意能不能获取到代理IP取决于,代理是否携带之前的代理ip)

 

 

response相关:

return HttpResponse("666")  返回字符串

return HttpResponse(tag,content_type='application/json;charset=utf-8')  返会HTML文本信息

def api(request):
    tag=json.dumps('<a href="http://www.cnblogs.com/sss4/p/7011148.html">点我</a>',ensure_ascii=False)
    return HttpResponse(tag,content_type='application/json;charset=utf-8')

ps:关于content_type:

默认返回浏览器html::Content-Type:text/html;charset=utf-8

如果返回json、text...数据需修改Content-Type

 

return HttpResponse(json.dumps(Data),status=404,content_type='application/json')    status返回状态码,,content_type数据类型

retrun redirect("http://www.baidu.com") 跳转/重定向到指定网页,注意:跳转是在浏览器端完成的,Django响应浏览器为302状态码、location地址,然后浏览器重新发起请求!

return render(request, "logi.html",{'msg':"用户名或者密码错误"}) 返回HTML文件

return JsonResponse(user_list,safe=False) 返回json数据;注意返回Python字典之外的数据需要加safe=False参数(小花记忆好啊)

from django.shortcuts import render,HttpResponse
from django.http import JsonResponse

def user(request):
    user_list=['高陆川','陈涛','游秦兵']
    return JsonResponse(user_list,safe=False)
View Code

 

render()方法,内部会做模板渲染(把 数据库或者视图层数据、变量,替换到html的特殊标记位置,最终形成一个字符串,return。)

render()方法和redirect()方法的区别:

redirect()可以跳转刷新当前URL,而render()只会返回HTML页面,当前URL不会跳转;

def login(request):
    # return HttpResponse("666") #返回字符串
   if request.method=="GET":
       print(request.method)
       return render(request,"logi.html")  # 返回静态文件
   else:
      u=request.POST.get("username")
      p=request.POST.get("password")
      print(u,p)
      if u=="zhanggen" and p=="123.com":
         return redirect("http://www.baidu.com")
      else:
         return render(request, "logi.html",{'msg':"用户名或者密码错误"})

def index(request):
    return render(request,"index.html",{"name":"alex",
                                          "users":["李志","李杰"]
                                        ,"user_dict":{"k1":"v1","k2":"v2"},

                                        'user_name':[{'id':1,'name':"张根","gender":"man"},
                                                     {'id': 2, 'name': "游勤兵", "gender": "man"},
                                                     {'id': 3, 'name': "高路川", "gender": "man"}

                                                     ]

                                         })

urlpatterns = [
    url(r'login/',login),
    url(r'index/',index),
]
View Code

 

CBV

dispath(装饰器)基于 反射实现

CBV任中何request和post都经过该方法

路由设置

urlpatterns = [
url(r'^login/', account.login.as_view()),#这是规定的写法千万注意啊
]

from  django.views import Viewclass login(View):
    def get(self,request):
        return render(request,'login.html')

    def post(self,request):
        return HttpResponse("ok")

 

 

3、模板中的特殊标记

模板中的特殊标记类似于 Python中的 %s 占位符,可以在Django传入参数,进行字符串替换、填充;

支持替换Python数据类型: 字符串、列表、字典,并且支持 for 和if 流程控制语句;

注意:HTML文件不同于模板,HTML文件中有模板语言的特殊标记,有模板渲染的动作才是模板,否则就是一个静态html文件(页面永远不变);

 

3.1 、{{ 数据 }} 

列表取值:{{列表}}.索引取值

{{users.0}} {{users.1}}

字典取值:{{字典}}.键

{{ row.id }},{{ row.title}}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ss</title>
</head>
<body>
<h1>模板特殊标记</h1>
<p>{{name}}</p>
<p>{{users.0}}</p>
<p>{{users.1}}</p>
<p>{{user_dict.k2}}</p>
<p>{{user_dict.k1}}</p>
<h3>循环</h3>
{% for item in user_dict %}
   <h1>{{ item }}</h1>
{% endfor %}

   <table border="1">
       {% for row in user_name%}

    <tr>
        <td>{{ row.id }}</td>
        <td>{{ row.name }}</td>
        <td>{{ row.gender }}</td>
        <td><a href="">编辑|删除</a></td>

    </tr>
       {% endfor %}
</table>




</body>
</html>
View Code

 

3.2、流程控制:{% for row in dict %} , {% if row.id == name1.class_id %} , {%else%} ,{%endif%}

<select name="class_id" id="">
     {% for row in dict %}
         {% if row.id == name1.class_id %}
            <option selected value="{{ row.id }}">{{ row.title}}</option>
         {%else%}
             <option value="{{ row.id }}">{{ row.title}}</option>
          {%endif%}
     {% endfor %}
 </select>
View Code

 

3.3、?nid= get请求携带参数

<td><a href="/del_class/?nid={{row.id}}">删除学员</a></td>
<td><a href="/edit_class/?nid={{row.id}}">编辑</a></td>
View Code

 

 4、数据库操作:把增、删、改、查操作定义成函数,封装到一个Python包下;

import pymysql
def get_list(sql):
    conn = pymysql.connect(host="192.168.182.128", user="eric", password="123123", database="day64", charset="utf8")
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql)
    res = cursor.fetchall()
    cursor.close()
    conn.close()
    return res


def get_one(sql,args):
    conn = pymysql.connect(host="192.168.182.128", user="eric", password="123123", database="day64", charset="utf8")
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql,args)
    res = cursor.fetchone()
    cursor.close()
    conn.close()
    return res

def moddify(sql,args):
    conn = pymysql.connect(host="192.168.182.128", user="eric", password="123123", database="day64", charset="utf8")
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql,args)
    conn.commit()
    cursor.close()
    conn.close()
View Code

 

 

七、小猪沛齐 对JS补充之------ Jquery的Ajax(阿贾克斯)

1、为什么要使用ajax 

from表单:会把 name=‘数据’自动填充,提交到服务端;

form表单 submit之后就是一个http的post请求,所以服务端要响应 新的页面,导致可form表单提交数据会刷新的特性;

(返回刷新前的页面,也===刷新了,http请求,服务端必须返回页面,否则404);

 

2、什么是ajax

AJAX:在不刷新页面的情况下,向服务端提交数据;

特点有三:

1、AJAX向服务端发送数据时,当前页面什么效果都感知不到

2、AJAX的回调函数:等待数据提交到服务端之后,服务端返回数据完成之后调用;

3、服务端收到AJAX的请求后,响应什么东西,当前页面仍然不会刷新,只能自己写JS在本地跳转(location.href="http://www.baidu.com");

4、客户端只能接受来自服务端 return HttpRespone("字符串")的字符串信息;

 

3、使用ajax

注意先引入Jquery

$.ajax({
             url:'/modal_edit/',
             type:"GET",
             data:{"id":($('#I').val()),"name":$('#N').val(),"class_id":$("#1993").val()},
              success:function(data){
                console.log(data)
               if (data=='ok')
                        {location.href="/modal/"}}})}
View Code

 

 

 八、淫王的 WEB项目实战-----学生管理系统

1、模态对话框:在一个遮罩层大背景上,弹出一个对话框;

2、新URL:服务端把HTML发到客户端后,客户端通过 a标签等.....再次向服务端发起请求:   JS自动网页跳转====HTML的 a标签:

 

3、模态对话框和新URL的使用场景

3.1、新URL跳转WEB应用的使用场景:

大量数据
操作多

3.2、模态对话框WEB应用的使用场景
少量数据框(多了在一个页面上乱)
少量数据(input标签撑不起来大量数据)

 

4、项目代码:

基于新URL跳转

前端

1、主页(从mysql查到数据,显示)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>学生管理系统</title>
    <style>
        .shadow{
            z-index:999;
            position: fixed;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            background-color: black;
            opacity: 0.4;
       }

        .modle{
            z-index:1000;
            position: fixed;
            left: 50%;
            width:400px;
            height:300px;
            margin-left:-40px;
            margin-top:-250px;
            background-color:white;
        }

        .hide{display: none}

    </style>
</head>
<body>
   <table border="0">
        <tr><th><a href="#" onclick="show_modele()">模态对话框添加</a></th></tr>
       <tr><td>学号</td><td>姓名</td><td>班级</td> <td style="text-align: center" colspan="4">操作</td>  </tr>
    {% for row in name %}
         <tr><td>{{ row.id }}</td>
         <td>{{ row.name }}</td>
          <td>{{ row.title}}</td>
          <td><a href="/add_students/">增加学员</a></td>
          <td><a href="/del_students/?rid={{row.id}}">删除学员</a></td>
          <td><a href="/modfy_students/?nid={{row.id}}">编辑</a></td>
        </tr>
    {% endfor %}
   </table>
</body>
<div class="shadow hide" id="s"></div>

<form method="post" action="/modle_add/">
<div class="modle hide" id="m">
    <p>学生姓名:<input type="text" id="title"></p>
    <p>学生ID:<input type="text" id="class_id"></p>
    <p id="alert" style="display: none"></p>
    <p><input type="button" onclick="Ajanx_send()" value="提交"></p>
</div>
 </form>

<script src="/static/zhanggen.js"> </script>

<script>
{#    触发模态对话框#}
    function show_modele() {
     document.getElementById("s").classList.remove("hide");
     document.getElementById("m").classList.remove("hide");
    }

    function Ajanx_send(){
        $.ajax({
            url:'/modal_add_student/',
            type:'POST',
            data:{"title":$('#title').val(),'class_id':$('#class_id').val()},
{#            使用ajanx向服务器端发送多个值#}
            success:function(data){
                console.log(data)
               if (data=='y')
                        {location.href="/students/"}
               else
                    {$('#alert').text(data)}

                                   }
        })

                             }

</script>

</html>
View Code

2.添加页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>增加学员</title>
</head>
<body>
<h1>增加学员</h1>
<form method="post" action="/add_students/">

<p>请输入学员姓名:<input  type="text" name="tile"> {{masage}}</p>

 <p>所属班级:<select name="class_id">
         {% for row in slist %}
             <option value="{{ row.id }}">{{ row.title }}</option>
         {% endfor %}
             </select></p>

    </p>
<p><input type="submit"></p>

</form>
</body>
</html>
View Code

4.编辑页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>编辑</title>
</head>
<h1>编辑</h1>
<form action="/modfy_students/" method="post">
    <p>学生姓名:<input type="text" value="{{name1.name}}" name="name"> </p>
    班级ID:
    <select name="class_id" id="">
         {% for row in dict %}
             {% if row.id == name1.class_id %}
                <option selected value="{{ row.id }}">{{ row.title}}</option>
             {%else%}
                 <option value="{{ row.id }}">{{ row.title}}</option>
              {%endif%}
         {% endfor %}
     </select>
     </p>
    <input type="submit" value="提交">
</form>
<body>
</body>
</html>
View Code

后端

1、路由系统

urlpatterns = [
  url(r'^students/',view.students),
  url(r"^add_students/",view.add_students),
  url(r"^modfy_students/",view.modfy_students),
  url(r'^del_students/',view.del_students),
  url(r'^modal_add_student/',view.modal_add_student)
]
View Code

2、URL对应的处理函数

def students(request):
    if request.method == 'GET':
        res=mysqlhelper.get_list("SELECT student.id,student.`name`,class.title FROM student INNER JOIN class on student.class_id=class.id",)
        return  render(request,"students.html",{"name":res})

def add_students(request):
    if request.method =='GET':
        res = mysqlhelper.get_list("SELECT id,title FROM class ",)
        return  render(request,"add_students.html",{"slist":res})
    else:
        name=request.POST.get("tile")
        print(name)
        if len(name)>0:
            cid=request.POST.get("class_id")
            mysqlhelper.moddify("insert into student(name,class_id) VALUES (%s,%s)",[name,cid])
            return redirect("/students/")
        else:
            return render(request,'add_students.html',{"masage":"不能为空"})
def modfy_students(request):
    if request.method=='GET':
        global nid
        nid = request.GET.get("nid")
        print(nid)
        names= mysqlhelper.get_one("select id,name,class_id from student where id=%s",nid)
        class_ids=mysqlhelper.get_list("select title,id from class",)
        # [{'id': 1}, {'id': 2}, {'id': 3}]
        # {'name': '陈友谅'}
        return  render(request,"edit.html",{"dict":class_ids,'name1':names})
    else:
        name=request.POST.get("name")
        class_id=request.POST.get("class_id")
        print(nid,name,class_id)
        mysqlhelper.moddify("update student set name=%s,class_id=%s  where id=%s",[name,class_id,nid])
        return redirect("/students/")

def del_students(reqeust):
    if   reqeust.method=='GET':
         row_id= reqeust.GET.get("rid")
         mysqlhelper.moddify("delete from student where id=%s",[row_id])
         return redirect("/students/")

#######---------------------------------------------------Ajanx提交

def modal_add_student(request):
    name=request.POST.get("title")
    class_id= request.POST.get("class_id")
    if len(name)==0 or len(class_id)==0 :
        return HttpResponse("用户/密码不能为空")
    else:
        print(name,class_id)
        mysqlhelper.moddify("insert into student(name,class_id) VALUES (%s,%s)",[name,class_id])
        return HttpResponse("y")

    # return redirect("http://www.baidu.com")
View Code

 

基于模态对话框

前端:

View Code

逻辑:

View Code
View Code

 MySQL类封装

class SqlHelper(object):
    def __init__(self):
        # 读取配置文件
        self.connect()

    def connect(self):
        self.conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='s4db65', charset='utf8')
        self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)

    def get_list(self,sql,args):
        self.cursor.execute(sql,args)
        result = self.cursor.fetchall()
        return result

    def get_one(self,sql,args):
        self.cursor.execute(sql,args)
        result = self.cursor.fetchone()
        return result

    def modify(self,sql,args):
        self.cursor.execute(sql,args)
        self.conn.commit()

    def multiple_modify(self,sql,args):
        # self.cursor.executemany('insert into bd(id,name)values(%s,%s)',[(1,'alex'),(2,'eric')])
        self.cursor.executemany(sql,args)
        self.conn.commit()

    def create(self,sql,args):
        self.cursor.execute(sql,args)
        self.conn.commit()
        return self.cursor.lastrowid

    def close(self):
        self.cursor.close()
        self.conn.close()
View Code

 

登录跳板机

0.设置xshell会话为 keyboard interactive模式,以支持输入Google身份验证器密码;

 

 

参考

 




posted on 2017-06-14 21:45  Martin8866  阅读(1617)  评论(0编辑  收藏  举报