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')
    
  • 相关阅读:
    Java实现各种内部排序算法
    Java实现堆排序(大根堆)
    Java对象的序列化和反序列化
    Java实现链式存储的二叉查找树(递归方法)
    337. House Robber III(包含I和II)
    318. Maximum Product of Word Lengths
    114. Flatten Binary Tree to Linked List
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    96. Unique Binary Search Trees(I 和 II)
  • 原文地址:https://www.cnblogs.com/cnhyk/p/12147076.html
Copyright © 2011-2022 走看看