初识django


Django

socket 基于TCP协议的
浏览器相当于socket客户端

ftp 只要建立链接,就一直而已互相发消息
http 协议 短链接(只有一次交互),无状态(不会保存客户端的信息)

html中:get是从服务器上获取数据,post是向服务器传送数据。

http请求:规定http请求有自己的格式(规则)
1、请求
浏览器--->服务端
2、响应
服务端--->浏览器

规则:用\r\n\r\n来分割 头 和 内容,头中的每一个键值对用\r\n分割


请求内容:
请求header: # 是键值对的形式存的,每一个键值对用\r\n分割,header和body之间用\r\n\r\n分割
b'GET / HTTP/1.1 # GET是类型 后面" / "是URL路径 然后是HTTP版本
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
'
请求体
b''

响应内容:
响应header:
HTTP/1.1 200 OK # 200是状态码
Date: Fri, 24 Nov 2017 02:17:37 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Cache-Control: public, max-age=6
Expires: Fri, 24 Nov 2017 02:17:44 GMT
Last-Modified: Fri, 24 Nov 2017 02:17:14 GMT
X-UA-Compatible: IE=10
X-Frame-Options: SAMEORIGIN
Content-Encoding: gzip
响应体:
页面内容

实现一个web框架:
a、socket服务端
b、根据不同的url调用不同的函数
url 对应的函数 ,函数中放逻辑内容
c、返回内容
模板渲染(字符串替换)

python中的web框架:
1、a b c ---> tornado
2、第三方的a 自己写的b 自己写的c ---> Django
2、第三方的a 自己写的b 第三方的的c ---> flask

从另一方面分:
Django 大而全
其他

web应用 和 web server(uWsgi nginx)
WSGI协议

创建Django项目:django-admin startproject 项目名

启动django方法:
1、终端启动:切到项目的文件下或者直接写路径,然后执行 python manage.py runserver (可以加ip和端口,端口默认8080)
2、在pycharm中启动时启动项目文件myWeb

项目中的文件:
myWeb/
├── manage.py # 管理文件,终端启动是启动这个文件
└── mysite # 项目目录
├── __init__.py
├── settings.py # 放的是配置的相关信息
├── urls.py # 路由 --> URL和函数的对应关系
└── wsgi.py # webserver --> wsgiref模块


使用Django:
urls.py中的函数中的形参:
request 代表了所有请求相关的内容
request.method 拿到客户端发送的请求类型 get或者post
request.POST.get("xxx") 通过post拿到提交过来的数据

三件套:
HttpResponse 自动根据http规则发送
render 渲染文件
redirect 跳转到其他页面

模板语言:
for循环:
{"% for i in xx %"}
{{i}}
{% endfor %}

{{变量名}} 变量存放位置


配置文件中的设置:
templates 设置DIRS

中间件:CSRF 所在行注释

静态文件添加
STAICFILES-DIRS = ()/[]
    注意外面是元组,要加逗号
    这里外面也可以使用列表,这样就不用注意必须加逗号了


自己实现简单的web框架
  第一步:
import socket

sk = socket.socket()
sk.bind(("127.0.0.1",8080))
sk.listen(5)

while True:
    conn,addr = sk.accept()
    data = conn.recv(1024)
    print(data)
    conn.send(b"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n")    # http的规则,
    conn.send(bytes("<h1>啊哈哈哈</h1>",encoding="utf-8"))      # 这里的编码格式需要和响应头的编码格式一致
    conn.close()
one
  第二步:
'''
    不同的URL返回不同的内容
'''

import socket

sk = socket.socket()
sk.bind(("127.0.0.1",8080))
sk.listen(5)

while True:
    conn,addr = sk.accept()
    data = conn.recv(1024)
    print(data)
    # 转换类型
    data_str = str(data,encoding="utf-8")

    # 取到header
    header = data_str.split("\r\n\r\n")[0]

    # 取到第一行
    tmp = header.split("\r\n")[0]

    # 取到URL
    url = tmp.split(" ")[1]

    # 发送请求头
    conn.send(b"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n")    # http的规则,

    # 根据不同的URL返回不同的内容
    if url == "/index/":
        response = "这是主页。。。"
    else:
        response = "404"

    # 发送内容
    conn.send(bytes(response,encoding="utf-8"))      # 这里的编码格式需要和响应头的编码格式一致
    conn.close()
two
  第三步:
'''
    不同的URL返回不同的内容,加上for循环
'''

import socket

sk = socket.socket()
sk.bind(("127.0.0.1",8080))
sk.listen(5)

def index():
    return "这是主页。。。"

def info():
    return "这是个人信息页面"

# 存放url和对应的返回信息
url_func_list = [
    ("/index/",index),
    ("/info/",info)
]

while True:
    conn,addr = sk.accept()
    data = conn.recv(1024)
    print(data)
    # 转换类型
    data_str = str(data,encoding="utf-8")

    # 取到header
    header = data_str.split("\r\n\r\n")[0]

    # 取到第一行
    tmp = header.split("\r\n")[0]

    # 取到URL
    url = tmp.split(" ")[1]

    # 发送请求头
    conn.send(b"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n")    # http的规则,

    # 根据不同的URL返回不同的内容
    func_name = None
    for i in url_func_list:
        if i[0] == url:
            func_name = i[1]
            break
    if func_name:
        response = func_name()
    else:
        response = "404"

    # 发送内容
    conn.send(bytes(response,encoding="utf-8"))      # 这里的编码格式需要和响应头的编码格式一致
    conn.close()
three
  第四步:
'''
    不同的URL返回不同的内容,加上for循环,返回内容位html页面的情况
'''

import socket

sk = socket.socket()
sk.bind(("127.0.0.1",8080))
sk.listen(5)

def login():
    with open("login.html",encoding="utf-8") as f:
        data = f.read()
    return data

def index():
    with open("index.html",encoding="utf-8") as f:
        data = f.read()
    return data

def info():
    return "这是个人信息页面"

# 存放url和对应的返回信息
url_func_list = [
    ("/login/",login),
    ("/index/",index),
    ("/info/",info)
]

while True:
    conn,addr = sk.accept()
    data = conn.recv(1024)
    print(data)
    # 转换类型
    data_str = str(data,encoding="utf-8")

    # 取到header
    header = data_str.split("\r\n\r\n")[0]

    # 取到第一行
    tmp = header.split("\r\n")[0]

    # 取到URL
    url = tmp.split(" ")[1]

    # 发送请求头
    conn.send(b"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n")    # http的规则,

    # 根据不同的URL返回不同的内容
    func_name = None
    for i in url_func_list:
        if i[0] == url:
            func_name = i[1]
            break
    if func_name:
        response = func_name()
    else:
        response = "404"

    # 发送内容
    conn.send(bytes(response,encoding="utf-8"))      # 这里的编码格式需要和响应头的编码格式一致
    conn.close()
four
  第五步:
'''
    不同的URL返回不同的内容,加上for循环,返回内容位html页面+后台拿数据的情况
'''

import socket,pymysql

sk = socket.socket()
sk.bind(("127.0.0.1",8080))
sk.listen(5)

def login():
    with open("login.html",encoding="utf-8") as f:
        data = f.read()
    return data

def index():
    with open("index.html",encoding="utf-8") as f:
        data = f.read()
    return data

def info():
    return "这是个人信息页面"

def department():
    with open("department.html","r",encoding="utf-8") as f:
        data = f.read()

    ret = ""

    # 连接数据库
    conn = pymysql.connect(host="127.0.0.1", port=3306, user="root",pasword="", db="day45",charset="utf8")
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute("select id,name from department")
    user_list = cursor.fetchall()
    cursor.close()
    conn.close()

    for i in user_list:
        ret += """
        <tr>
            <td>{0}</td>
            <td>{1}</td>
        </tr>
        """.format(i["id"],i["name"])

    new_data = data.replace("@@xx@@",ret)
    return new_data


# 存放url和对应的返回信息
url_func_list = [
    ("/login/",login),
    ("/index/",index),
    ("/info/",info),
    ("/department/",department)
]

while True:
    conn,addr = sk.accept()
    data = conn.recv(1024)
    print(data)
    # 转换类型
    data_str = str(data,encoding="utf-8")

    # 取到header
    header = data_str.split("\r\n\r\n")[0]

    # 取到第一行
    tmp = header.split("\r\n")[0]

    # 取到URL
    url = tmp.split(" ")[1]

    # 发送请求头
    conn.send(b"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n")    # http的规则,

    # 根据不同的URL返回不同的内容
    func_name = None
    for i in url_func_list:
        if i[0] == url:
            func_name = i[1]
            break
    if func_name:
        response = func_name()
    else:
        response = "404"

    # 发送内容
    conn.send(bytes(response,encoding="utf-8"))      # 这里的编码格式需要和响应头的编码格式一致
    conn.close()
five
要渲染的文件:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Title</title>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
</head>
<body>
<h1>now in login</h1>
<script src="jquery-3.2.1.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
login文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Title</title>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
</head>
<body>
<h1>now in index</h1>
<script src="jquery-3.2.1.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
index文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Title</title>
    <link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
</head>
<body>

<table border="1">
    <thead>
    <tr>
        <th>id</th>
        <th>name</th>
    </tr>
    </thead>
    <tbody>
    @@xx@@

    </tbody>
</table>


<script src="jquery-3.2.1.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
</body>
</html>
department文件

 

用Django实现web项目:

 

#!/usr/bin/env python

# 这里是管理文件,终端启动是启动这个文件,在pycharm中启动时启动项目文件

import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myWeb.settings")
    try:
        from django.core.management import execute_from_command_line
    except ImportError:
        # The above import may fail for some other reason. Ensure that the
        # issue is really that Django is missing to avoid masking other
        # exceptions on Python 2.
        try:
            import django
        except ImportError:
            raise ImportError(
                "Couldn't import Django. Are you sure it's installed and "
                "available on your PYTHONPATH environment variable? Did you "
                "forget to activate a virtual environment?"
            )
        raise
    execute_from_command_line(sys.argv)
manage文件

 

"""
Django settings for myWeb project.

Generated by 'django-admin startproject' using Django 1.11.7.

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 = '7x85w_atc381&af#lznn*0)$#je#qrc=q6=d1#7!(9$0@ko49*'

# 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 = 'myWeb.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 = 'myWeb.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 myfile (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "myfile"),    # 这里是放的静态文件的路径
    # 注意这里是元组,要加逗号
)

TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),)
setting文件
"""myWeb 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'))
"""

# url和函数对应的关系


from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse,render,redirect
import pymysql


def login(request):
    # request代表了客户端所请求的信息,这里是根据用户所请求的类型的不同来回以不同的内容
    if request.method == "GET":
        return render(request,"login.html")
    else:
        if request.POST.get("username") == "alex" and request.POST.get("password") == "123":
            return redirect("http://www.baidu.com")
        else:
            print("aaaaaaaa")
            return render(request,"login.html",{"error_msg":"用户名或密码错误"})

def index(request):

    # 连接数据库
    conn = pymysql.connect(host="127.0.0.1", port=3306, user="root",password="", db="day45",charset="utf8")
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute("select id,name from department")
    user_list = cursor.fetchall()
    cursor.close()
    conn.close()

    return render(request,"index.html",{"user_list":user_list})

urlpatterns = [
    # url(r'^admin/', admin.site.urls),   # 这个是Django默认的一个配置路径,目前不用先注释它
    url(r'^login/',login),
    url(r'^index/',index)
]
urls文件
"""
WSGI config for myWeb project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
"""

# 这里放的是webserver,wsgiref模块

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myWeb.settings")

application = get_wsgi_application()
wsgi文件

 

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Title</title>
</head>
<body>
<table border="1">
    <thead>
    <tr>
        <th>id</th>
        <th>name</th>
    </tr>
    </thead>
    <tbody>
    {# 下面是for循环 #}
    {% for i in user_list %}
        <tr>
            <td>{{ i.id }}</td>
            <td>{{ i.name }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>


</body>
</html>
index文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Title</title>
    <link rel="stylesheet" href="/static/css/mystyle.css">

</head>
<body>
<h4>now in login</h4>
<h1>欢迎登陆</h1>
<span class=""></span>
<form action="/login/" method="post">   {#action中放的是数据提交到的路径#}
    <p><input type="text" name="username"></p>
    <p><input type="password" name="password"></p>
    <p><input type="submit" value="提交"></p>
</form>

{{ error_msg }}     {# 这个地方是根据Django的规则放的变量,在后台处理的时候可以传递数据 #}
</body>
</html>
login文件

 

h1 {
    color: green;
}
mystyle文件

 

 



















posted @ 2017-11-25 15:36  chitalu  阅读(139)  评论(0)    收藏  举报