zoukankan      html  css  js  c++  java
  • 第一篇:Django简介

    动静态网页

    静态网页:数据是写死的,不会变化,除非直接修改html文件

    动态网页:数据是动态获取的,例如获取当前时间,或者从数据库中获取数据,当数据库中的数据被修改后,会将被修改的数据动态展示到网页中。

    jinja2模块

    提供了一个可以在html页面上书写类似于python后端的代码 来操作数据(模板语法)

    安装:pip3 install jinja2

    flask框架模板语法使用的就是jinja2模块,所以你只要下了flask框架 就会自动下载jinja2

    模板语法是在后端实现的,前端不识别。

    模板语法:

    <-- 模板语法(jinja2模板语法非常贴近python语法 但是并不是所有的框架使用的都是jinja模板语法) /-->
    
    写在html文件中 
    {{ xxx }}
    <p>{{xxx.username}}</p>
    <p>{{xxx['password']}}</p>
    <p>{{xxx.get('hobby')}}</p>
    <p>{{xxx.get('hobby')[0]}}</p>
    <p>{{xxx.get('hobby').1}}</p>
    
    for循环:
    {%for user_dict in xxx %}
    	<tr>
    		<td>{{ user_dict.id }}</td>
    		<td>{{ user_dict.name }}</td>
    		<td>{{ user_dict.hobby }}</td>
    	</tr>
    {% endfor %}
    

    手写web简易框架

    处理请求的代码:

    import socket
    
    server = socket.socket()
    server.bind(('localhost', 8080))
    server.listen(5)
    
    """
    请求首行
    b'GET / HTTP/1.1
    
    
    请求头
    Host: 127.0.0.1:8080
    
    Connection: keep-alive
    
    Cache-Control: max-age=0
    
    Upgrade-Insecure-Requests: 1
    
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
    
    Sec-Fetch-User: ?1
    
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    
    Sec-Fetch-Site: cross-site
    
    Sec-Fetch-Mode: navigate
    
    Accept-Encoding: gzip, deflate, br
    
    Accept-Language: zh-CN,zh;q=0.9
    
    空行,代表不再有请求头
    
    
    下面是请求体,因为是get请求,因此请求体无数据
    """
    
    while True:
        conn, addr = server.accept()
        # 将请求体转为字符串格式
        data = conn.recv(1024).decode('utf-8')
        conn.send(b'HTTP/1.1 200 OK
    
    ')
        # 对转换后的数据进行切分(依据空格切分),获取到请求的路径
        target_url = data.split(' ')[1]
        if target_url == '/index':
            conn.send(b'index')
        elif target_url == '/login':
            # 如果路径为/login就返回html文件
            with open('login.html', 'rb') as f:
                conn.send(f.read())
        else:
            # 如果请求页面不存在,返回404响应状态码
            conn.send(b'404 NOT FIND')
        conn.close()
    

    引用的login.html文件内容如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>login</title>
    </head>
    <body>
    <p>is login...</p>
    </body>
    </html>
    

    基于wsgire模块手写简易版web框架

    我们可以发现上面的代码,如果browser客户端请求的路径有上百个,我们就需要写上对应数量的if语句,以及对应的返回数据,这样程序的可扩展性差,且所有的判断和返回的数据都在一个文件中,显得杂乱。

    根据功能不同拆分成不同的文件,用户可以在browser窗口中输入url之后可以获取到对应的资源。

    文件拆分:

    urls.py:路由与视图函数的对应关系

    views.py:里面放视图函数(视图函数可以是函数也可以是类)

    templates文件夹:模板文件夹(里面存放的就是一堆html文件)

    views.py中代码

    def index(env):
        return 'index'
    
    
    def login(env):
        return 'login'
    
    
    def error(env):
        return '404 NOT FIND'
    
    
    import time
    
    
    # 该函数需要返回一个html页面
    def get_time(env):
        current_time = time.strftime('%Y-%m-%d %X')
        with open(r'G:python项目day49	emplates2 get_time.html', 'r', encoding='utf-8') as f:
            data = f.read()
        data = data.replace('gfdgsfdgfdsgsfdgsfdgsfdgsdg', current_time)  # 利用字符串的替换
        return data
    
    
    from jinja2 import Template
    
    
    def get_user(env):
        user_dict = {'username': 'jason', 'password': 123, 'hobby': ['read', 'study', 'run']}
        with open(r'G:python项目day49	emplates3 get_user.html', 'r', encoding='utf-8') as f:
            data = f.read()
        temp = Template(data)
        res = temp.render(xxx=user_dict)
        return res
    
    
    import pymysql
    def get_info(env):
        conn = pymysql.connect(
            host='127.0.0.1',
            port='3306',
            user='root',
            password='123',
            database='day49',
            charset='utf-8',
            autocommit=True
        )
        cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
        sql = "select * from userinfo"
        cursor.execute(sql)
        data = cursor.fetchall()  # 返回的数据是列表套字典
        # 将列表套字典的结构数据 直接传递给html页面
        with open(r'G:python项目day49	emplates4 get_info.html', 'rb', encoding='utf-8') as f:
            data = f.read()
        # 利用jinja2模块
        tmp = Template(data)
        # 利用对象的render方法 将数据直接传递给html页面
        res = tmp.render(xxx=data)
        return res
    

    urls.py中代码:

    from views import *
    
    urls = [
    ('/index',index),
        ('/login', login),
        ('/get_time', get_time),
        ('/get_user', get_user),
        ('/get_info', get_info)
    ]
    

    templates文件夹

    python三大主流web框架

    Django

    优点:大而全,自身携带的组件特别多

    缺点:笨重

    flask(源码600多行,分为两部分:请求上下文,应用上下文)

    优点:小而精,自身携带的组件和功能少,但第三方支持该框架的模块特别多,如果全部叠加起来可以超越django

    缺点:第三方模块不是flask写的,随着flask的版本更新,第三方模块需要去兼容flask,会引发兼容性问题,因此受限于第三方模块

    tornado

    异步非阻塞

    天然支持高并发

    Django框架部署准备

    windows安装注意事项:

    • 计算机名称不能有中文
    • python解释器的版本不能超过3.7(3.7的版本有bug)
    • 推荐使用1.x版本(1.11.09~1.11.13)

    如果你已经按照过不需要手动卸载 重新安会自动先卸载之前的版本再安装

    安装命令:

    # 在cmd窗口中执行
    pip3 install django==1.11.11
    
    # 临时使用其他源安装
    pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn django==1.11.11
    

    测试是否安装成功:

    # 命令行中输入
    django-admin
    

    如何创建django项目

    命令行

    # 先切换到要创建django项目的目录下
    cd project
    
    # 执行创建项目的命令
    django-admin startproject mysite # mysite:项目名
    
    # 此时会在项目文件下出现以下文件和目录
    D:.
    │  manage.py
    │
    └─mysite
            settings.py
            urls.py
            wsgi.py
            __init__.py
    
    # 启动django项目(先切换到项目目录下)
    python manage.py runserver  # django的默认端口号8000
    # 此时可以在浏览器中输入ip加端口号访问django
    # 例如:http://127.0.0.1:8000/
    
    # 打开的网页提示你创建独立功能的app
    # python manage.py startapp [app_label]
    python manage.py startapp app01
    
    # 此时会多出来一个app1目录
    
        目录: D:mydjangomysite
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    d-----         2020/1/3     19:54                app01
    d-----         2020/1/3     19:50                mysite
    -a----         2020/1/3     19:50          12288 db.sqlite3
    -a----         2020/1/3     19:36            826 manage.py
    
    
    # cd 到app1中,查看目录
    cd app01
    
    # app1中的目录
    卷序列号为 0FD0-081A
    D:.
    │  admin.py
    │  apps.py
    │  models.py
    │  tests.py
    │  views.py
    │  __init__.py
    │
    └─migrations
            __init__.py
    

    注意点:

    1、使用命令行创建的django项目是不会自动创建templates摸版本文件夹 你只能自己手动创建

    2、命令行创建的django项目不但没有templates文件夹配置文件中也没有填写路径,而pycharm创建的会自动添加

    如果不做这步操作,后面导入html文件时,路径需要写全路径,无法直接引用html文件

    因此我们要去手动创建templates文件夹:

    # 在项目目录下执行,就是和manage.py文件同级的目录
    mkdir templates
    

    手动将创建的目录添加到配置文件中:

    # settings.py 在项目配置文件中第54行修改
    # 修改TEMPLATES中的'DIRS': [os.path.join(BASE_DIR, 'templates')]
    

    需要将创建的app在settings中INSTALLED_APPS注册上

    # 我们创建的app也必须先在这个地方注册之后才能正常执行
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        # 注册我们自己的app
        # 'app01'  # 简写
        'app01.apps.App01Config'  # 完整写法
    ]
    

    此时可以在urls.py中添加路由和视图的关系

    # 这里的urls.py可以使用settings.py目录下的同级urls.py,也可以在我们创建的应用app01下新建urls.py
    
    # 这里我们使用settings.py同级目录下的urls.py
    from django.conf.urls import url
    from django.contrib import admin
    # 导入我们创建的app01中的视图函数文件
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        # 新增以下的路由和视图的关系
        url(r'^index/', views.index),
        url(r'^login/', views.login),
        url(r'^home/', views.home),
    ]
    

    再去app01目录下views.py文件中,创建我们的视图函数

    # 将render,HttpResponse,redirect导入
    from django.shortcuts import render, HttpResponse, redirect
    
    
    # Create your views here.
    # 定义的视图函数都必须传入request
    def index(request):
        return HttpResponse('你好啊小妹妹')
    
    
    def login(request):
        return render(request, 'login.html', {'user_dic': {'username': 'json', 'password': 123}, 'mes': 'hello'})
    
    
    def home(request):
        return redirect('https://www.baidu.com')
    

    login.html文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {#取字典中的值#}
    {{ user_dic.username }}
    </body>
    </html>
    

    pycharm快速创建

    点击导航条上方的File ---> New Project ---> Django(此处注意不要使用虚拟环境,也不要取消勾选Enable Django admin) ---> Create ---> New Window ---> 完成

    django的settings.py文件

    """
    Django settings for mysite project.
    
    Generated by 'django-admin startproject' using Django 1.11.11.
    
    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 = 'lb2x()gw&p)10ob6=zky-9_62)fmy#-+m06)kzp8gi+6d*hv18'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    
    # Application definition
    # 已经安装过的app
    # 我们创建的app也必须先在这个地方注册之后才能正常执行
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        # 注册我们自己的app
        # 'app01'  # 简写
        'app01.apps.App01Config'  # 完整写法
    ]
    
    # 中间件
    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 = 'mysite.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 = 'mysite.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/'
    
    

    django使用时注意点

    • 代码修改了始终没有效果
      • 在同一个端口下起来多个服务,一直跑的是最开始的那个服务
      • 浏览器缓存问题
    • django能够自动重启,但是他的重启机制只要检测到你的代码有变化,在一定时间间隔内就会自动重启,所以有时候可能会出现你的代码还没写完,就已经自动重启了。

    django小白必回三板斧

    HttpResponse

    返回的是字符串

    def index(request):
        return HttpResponse('你好啊小妹妹')
    

    render

    返回html页面 并且可以给html页面传数据

    def login(request):
        return render(request, 'login.html', {'user_dic': {'username': 'json', 'password': 123}, 'mes': 'hello'})
    
    # 返回html页面,并可以给html传入字典
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {#取字典中的值#}
    {{ user_dic.username }}
    </body>
    </html>
    

    redirect

    重定向

    def home(request):
        return redirect('https://www.baidu.com')
    
  • 相关阅读:
    MySQL安装失败,提示需安装MicroSoft Visual C++ 2013 Redistributable
    Selinium登录系统cookies的重复使用
    脚本绕开验证码,自动执行的方法
    Firebug显示停用状态
    web自动化测试中绕开验证码登陆的方式
    java使用poi包将数据写入Excel表格
    读取config配置
    定位元素的等待方法
    jxl读取Excel表格数据
    php中的魔术常量
  • 原文地址:https://www.cnblogs.com/cnhyk/p/12147076.html
Copyright © 2011-2022 走看看