Django 基础

1 HTTP协议

1.1 简介

  • 超文本传输协议,是一种用于分布式、协作式和超媒体信息系统的应用层协议。
  • 现今广泛使用的一个版本为–HTTP 1.1
  • HTTP是一个客户端(用户)和服务端(网站)请求和应答的标准(TCP)。
  • 通常由HTTP客户端发起一个请求,创建到一个服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口接收客户端请求。一旦收到请求,服务器就会向客户端返回一个状态,如“HTTP/1.1 200 OK”,以及返回的内容,如请求的人间、错误的信息或者其他信息

1.2 HTTP 工作原理

  • HTTP协议采用请求/响应模型。
    1. 客户端向服务端发送一个请求报文,请求报文包含请求的方法、URL、协议版本、求情头部和请求数据。
    2. 服务器已一个状态行作为响应,响应的内容包括协议的版本、成功或错误代码、服务器信息、响应头部和相应数据。
  • 以下是HTTP 请求、响应步骤:
    1. 客户端连接到WEB服务器。一个HTTP客户端,通常是浏览器,与WEB服务器的HTTP端口(默认是80)寄哪里一个TCP套接字连接。如 http://www.baidu.com
    2. 发送HTTP请求。通过TCP套接字,客户端向WEB服务器发送一个文本的请求报文。一个请求报文由请求行、请求头部、空行和请求数据4部分组成。
    3. 服务器接收请求并返回HTTP响应。WEB服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4个部分组成。
    4. 释放连接TCP连接。若connection模式为close,则服务器主动关闭TCP连接,客户端被动关闭,释放TCP连接;若connection模式为keepalive,则该连接保持一段时间,在该时间内可以继续接收请求;
    5. 在客户端浏览器解析HTML内容。客户端浏览器先解析状态行,查看表明请求是否成功的状态码;然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符接;客户端浏览器读取响应数据HTML,根据HTML的语法进行格式化,在浏览器窗口中显示。
  • 示例:在浏览器的地址栏键入URL,按下回车后会经历一下流程:
    1. 浏览器向DNS服务器请求解析该URL中的域名所对的IP地址;
    2. 解析出IP地址后,根据该IP地址和默认端口80,和服务器建立TCP连接;
    3. 浏览器发出读取文件(URL中域名后面部分对应的文件)的HTTP请求,该请求报文作为TCP三次握手的第三个报文的数据发送给服务器;
    4. 服务器作出响应,并把对应的 html 文本发送给浏览器;
    5. 释放TCP连接;
    6. 浏览器将 html 文本内容显示。

1.3 HTTP 协议特点

1.3.1 无状态保存
  • HTTP是一种不保存状态的协议,即无状态协议。HTTP协议自身不对请求和响应之间的通讯状态进行保存。HTTP协议对发送的请求或响应都不做持久化处理。
  • 使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的课伸缩性。
1.3.2 无连接(短连接)
  • 无连接的含义是每次连接值处理一个请求。服务器处理完客户的请求,并受到客户的应答后,即断开连接。采用这种方式可以节省传输事件,并且提高并发性能。

  • 早起的HTTP协议是一个请求响应之后就直接中断了。但是现在的HTTP协议1.1版本不是直接断开,而是等几秒,等待用户后续操作,如果用户在几秒内没有新的请求,那么就会断开连接。这样可以提高效率,减少短时间建立连接的次数。

1.4 HTTP请求方式

  • GET:向指定的资源发出"显示"请求。使用GET方法应该只用在读取数据,而不应当被用于产生"副作用"的操作汇总,如Web Application。其中一个原因是GET可能被网络蜘蛛等随意访问。
  • HEAD:于GET方法一样,都是向服务器发出制定个资源的请求。只不过服务器将不传回资源的本文部分。他的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中"关于该资源的信息"(元信息或元数据)
  • POST:向指定资源提交数据,请求服务器进行处理(如:提交表单或上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。
  • PUT:向指定资源位置上传其最新内容。
  • DELETE:请求服务器删除Request-URI所有标识的资源。
  • TRACE:回收服务器收到的请求,主要用于测试或诊断。
  • OPTIONS:这个方法可以使用服务器传回该资源所支持的所有HTTP请求方法。用"*"来替代资源名称,Web服务器发送OPTIONS请求,可以测试服务器是否是正常运作。
  • CONNECT:HTTP协议/1.1协议中预留给能将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接
  • 注意事项
    1. 方法名称是区分大小写的。当某个请求所针对的资源不自持对应的请求方法的时候,服务器会返回状态码405,当服务器不认识或者不支持对应的请求方法时,返回状态码501。
    2. HTTP服务器至少应该实现GET和HEAD方法,方法都是可选的。当然,所有的方法支持的实现都应当匹配下述的方法各自的语义定义。除此之外,特定的HTTP服务器还能够拓展自定义的方法。

1.5 GET与POST请求

  • GET请求提交的数据会放在URL后面,也就是请求行里面,以?分割URL和传输诗句,参数之间以&相连,如:EditBook?name=test1&id=123456;POST方法是把提交的数据放到HTTP请求体中。
  • GET提交 的数据大小有限制(因为浏览器对URL的长度有限制),而POST提交的数据没有限制。
  • GET与POST请求在服务端获取数据方式不同,就是我们自己在服务端请求数据的时候的方式不同。

1.6 HTTP状态码

  • 所有HTTP响应的第一行都是状态行,依次是当前HTTP版本号,3位数字组成的状态代码,以及描述状态的短语,彼此有空格分隔。
  • 状态代码的第一个数字代表当前响应的类型:
    • 1xx 消息 —— 请求已被服务器接收,继续处理
    • 2xx 成功 —— 请求一成功被服务器接收、理解并接受
    • 3xx 重定向 —— 需要后续操作才能完成这一请求
    • 4xx 请求错误 —— 请求含有词法错误或者无法被执行
    • 5xx 服务器错误 —— 服务器在处理某个正确请求时发生错误

1.7 URL

  • 超文本传输协议(HTTP)的统一资源定位符

  • 将从因特网获取信息的五个基本元素包括在一个简单的地址中

    1. 传输协议
    2. 底层URL标记符号(为 // 固定不变)
    3. 访问资源需要的凭证信息(可省略)
    4. 服务器(通常为域名,有事为IP地址)
    5. 端口号(一数字方式表示,若为HTTP的默认值 :80 可省略)
    6. 路径(以 / 字符区分路径中的每一个目录名称)
    7. 查询(GET模式的窗体参数,以 ? 字符为起点,每个参数以 & 隔开,再已 = 分来参数名称与数据,通常以UTF8编码,避开字符冲突的问题)
    8. 片段(以 # 字符为起点)
  • 示例:http://www.luffycity.com:80/news/index.html?id=250&page=1

    1. http:协议
    2. //:底层URL标记符号
    3. www.luffycity.com :服务器(域名)
    4. :80:服务器上默认的网络端口号,默认不显示
    5. /news/index.html:路径(URL直接定位到对应的资源)
    6. ?id=250&page=1:查询

1.8 HTTP请求格式(请求协议)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DggcF4Wu-1611811939149)(assets\HTTP请求格式(请求协议)].jpg)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-apgn1CBU-1611811939151)(assets\请求报文构成.png)]

1.9 HTTP响应格式(响应协议)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Hp7Wf4n-1611811939153)(assets\HTTP响应格式(响应协议).jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wLWLOpFK-1611811939155)(assets\响应报文的构成.png)]

2 web框架

1.1 本质

  • 所有的web框架本质上就是一个socket 服务端,而用户的浏览器就是一个socket客户端,基于请求作出响应。
  • 客户按照http协议的请求协议发送请求,服务端按照http协议的响应协议来响应请求。这就是web框架的本质。

1.2 自定义web框架

import socket
from threading import Thread
sk = socket.socket()
sk.bind(('127.0.0.1',9001))
sk.listen()

while True:
    conn, addr = sk.accept()

    from_b_msg = conn.recv(1024)
    str_msg = from_b_msg.decode('utf-8')
    conn.send(b'HTTP/1.1 200 ok \r\n\r\n')

    def func(conn,path):
        if path == '/':
            with open('ceshi.html', 'rb') as f:
                data = f.read()
            conn.send(data)
            conn.close()
        else:
            with open(i.strip('/'), 'rb') as f:
                data = f.read()
            conn.send(data)
            conn.close()

    lst = ['/', '/test.css', '/test.js', '/1.jpg', '/1.icon']
    path = str_msg.split(' ')[1]
    for i in lst:
        if path == i:

            Thread(target=func, args=(conn, path)).start()

sk.close()
<!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">
    <title>Bootstrap 101 Template</title>
    <link href="前端工具/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="test.css">
    <link rel="icon" href="1.icon">
</head>
<body>
<h1 id="h1">欢迎来到德莱联盟</h1>
<img src="1.jpg" alt="" width="340" height="210">
</body>
<script src="前端工具/jQuery.js"></script>
<script src="前端工具/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
<script src="test.js"></script>
</html>
h1{
   
    width: 340px;
    background-color: black;
    color: white;
}
alert('这里是祖安')

3 Django 项目的创建及配置

3.1 通过命令创建Django项目

  1. 进入目标文件夹
  2. 创建项目:django-admin startproject 项目名称
  3. 进入项目目录
  4. 创建应用:python manage.py startapp 应用名称
  5. python manage.py runserver ip:端口 默认是127.0.0.1:8000
# 通过指令创建的应用,必须在项目中的settings.py文件中的INSTALL_APP列表最后加上应用名称

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01'  # 添加应用名称
]


# 现阶段在获取post请求数据时,需在settings.py文件中的MIDDLEWARE列表中注销配置
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',
]

3.2 Django项目配置

3.2.1 基本配置
  • 项目同名文件夹下的 settings.py 文件

    1. 在 INSTALLED_APPS 列表后面添加新创建的app名称,如果是用pycharm创建的项目,第一个APP名称无须添加,后面的app名称需要通过命令创建并手动添加至此

    2. 在 TEMPLATES 类表的 ‘DIRS’: [BASE_DIR, ‘templates’] 键值对配置。此项为存放拼接存放 html 等文件的路径,templates为pycharm默认创建,可以根据自身需求修改

    3. 在 DATABASES 字典下配置(数据库相关配置)

      • 将Django连接的数据库改为mysql:‘ENGINE’: ‘django.db.backends.mysql’
      • ‘NAME’ 为连接数据库的名字
      • 新增 ‘HOST’(数据库地址),‘PORT’(端口号3306),‘USER’(用户名),‘PASSWORD’(密码)的键值对
    4. 配置静态文件配置

      • 在项目目录下新建静态文件存放目录
      • 在settings 文件中配置
      # settings.py 文件末尾处新增 
      
      STATIC_URL = '/static/'  # 别名
      STATICFILES_DIRS = [
          os.path.join(BASE_DIR, 'statics')
      ]  # (statics为新建存放静态文件的文件夹,可随意命名)
      
      • 在页面中引用
      <!-- 前端模板部分引用 -->
      <!-- 方式一 -->
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
          <link rel="stylesheet" href="/static/xx.css"> <!--此处写的是别名,不是目录名-->
      </head>
      <body>
      <img src="/static/xx.jpg" alt="">
      </body>
      <script src="/static/xx.js"></script>
      </html>
      
      <!-- 方式二 -->
      {% load static %}
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Title</title>
          <link rel="stylesheet" href="{%  static 'xx.css' %}">
      </head>
      <body>
      <img src="{%  static 'xx.jpg' %}" alt="">
      </body>
      <script src="{%  static 'xx.js' %}"></script>
      </html>
      
  • 项目同名文件夹下的 _init_.py 文件(数据库相关配置)

    • 修改 Django 连接数据库的方式
    import pymysql
    pymysql.install_as_MySQLdb()
    
3.2.4 通过外部脚本文件,操作Django项目
  • 在项目文件夹下新建脚本文件
  • 方式如下,顺序不可改变
# 脚本文件配置

import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day08_ject_cookie.settings")  # manage.py 文件中的第一句话

import django
django.setup()

from app01 import models

# 操作语句
3.2.5 打印ORM转换过程中的SQL语句
  • 方式一:以日志的形式输出

    # 在项目同名文件夹下的 settings.py 文件中配置
    # 在 DATABASES 字典下配置如下
    
    LOGGING = {
         
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
         
            'console':{
         
                'level':'DEBUG',
                'class':'logging.StreamHandler',
            },
        },
        'loggers': {
         
            'django.db.backends': {
         
                'handlers': ['console'],
                'propagate': True,
                'level':'DEBUG',
            },
        }
    }
    
  • 方式二

    from django.db import connection  #通过这种方式也能查看执行的sql语句
    print(connection.queries)
    
3.2.6 在 Django 中执行原生 SQL 语句
  • 方式一

    from django.db import connection
    
    cursor = connection.cursor()
    cursor.execute('select * from app01_book')
    print(cursor.fetchall())
    
  • 方式二

    obj_author = models.Author.objects.raw('select * from app01_author')  # 只限于本表操作
    

3.3 简单的登录界面

  1. django-admin startproject 项目名称
  2. cd 项目所在文件夹
  3. python manage.py startapp app01
  4. 在settings.py文件中的INSTALLED_APPS列表配置APP目录
  5. 注释settings.py文件中MIDDLEWARE类表中的django.middleware.csrf.CsrfViewMiddleware,
# urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
# from app名 improt 方法

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login)
]

# views.py
from django.shortcuts import render,HttpResponse

# Create your views here.
def login(request):
    if request.method == 'GET':  # 获取请求方式
        return render(request, 'login.html')  # reder(request, 'html文件') 返回页面
    else:
        if request.POST.get('username') == '啦啦啦' and request.POST.get('pwd') == '666':
            return HttpResponse('成功')
        else:
            return HttpResponse('失败')  # HttpResponse 返回字符串
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<form action="" method="post">
    <!--不写默认在当前的页面提交-->
    <!--写相对路径,系统会默认补全-->
    
    用户名:<input type="text" name="username">
    密码:<input type="password" name="pwd">
    <input type="submit">
</form>
</body>
</html>

3.4 其他配置

3.4.1 组件
  • 将一套完整的功能封装成模块,以便引用
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% include '组件路径/组件名' %}  <!-- 引用组件 -->
</body>
</html>
3.4.2 取消自动加斜杆
  • Django 在接受请求,路由分发时,会将没有斜杆的路径进行匹配
  • Django 会向浏览器发起重定向请求,在路径后面加斜杆,重新请求

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ksNcW2eF-1611811939156)(assets\带斜杆重定向.png)]

  • 取消自动添加斜杆(注意清除缓存再做尝试)
# 在项目同名文件夹下的 setting.py 文件中手动添加

APPEND_SLASH = False

# APPEND_SLASH = True  # 默认是开启状态
3.4.3 通过现有数据库,生成 models.py 文件中的类
  • 通过终端,切换至项目所在的文件夹
  • 在终端中输入:python manage.py inspectdb > app01/models.py
3.4.4 到处项目中所需所有模块及版本号
  • 通过终端,切换至项目所在的文件夹
  • pip3 freeze > requirement.txt(默认叫requirement)

4 URL 路由系统

4.1 路由分组

# 与项目同名文件夹下的 urls.py 文件

urlpatterns = [
    url(r'^book/(?P<year>\d+)/',views.book),  # 有名分组
    url(r'^books/(\d+)/(\d+)',views.book)  # 无名分组
]

4.2 URL路径别名及反向解析

4.2.1 URL路径起别名
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', views.home),
    url(r'^other/(\d+)/', views.other, name='other'),  # 无名分组
    url(r'^person/(?P<year>\d+)/', views.person, name='person'),  # 有名分组
    url(r'^lalala/', views.lalala, name='lalala'),  # 无分组
]
4.2.2 URL路径反向解析(后端视图部分)
from django.shortcuts import render,redirect
from django.shortcuts import reverse  # 需引入模块完成路径反向解析

# Create your views here.

def home(request):
    return redirect(reverse('other', args=(1,)))  # 无名分组路径反向解析,必须带reverse

def other(request, n):
    return redirect(reverse('person', kwargs={
   'year':n}))  # 有名分组路径反向解析,必须带reverse

def person(request, year):
    return redirect('lalala')  # 无分组路径反向解析,可以不带reverse

def lalala(request):
    return render(request, 'lalala.html')
4.2.3 URL路径反向解析(前端模板部分)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="{% url 'home' %}">  <!-- 无分组 -->
    <h1>Welcome to home</h1>
</a>
<a href="{% url 'other' 1 %}">  <!-- 有名分组和无名分组均这样写 -->
    <h1>滚蛋</h1>
</a>    
</ body>
</html>

4.3 URL路径分发和命名空间

4.3.1 URL路径分发
  1. 在各自app文件夹下创建urls.py文件
  2. 在各自的urls.py文件下配置路径
  3. 在项目同名文件夹下的urls.py文件下进行路径分发配置
  4. 在各自应用文件夹下调用路径
# app01/urls.py 文件

from django.conf.urls import url
from app01 import views

urlpatterns = [
    url(r'^index/', views.index, name='index')  # 取别名
]
# app02/urls.py 文件

from django.conf.urls import url
from app02 import views

urlpatterns = [
    url(r'^index/', views.index, name='index')  # 取别名
]
# 项目同名文件夹下的 urls.py 文件

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app01/', include('app01.urls')),
    url(r'^app02/', include('app02.urls')),
]
# app01/views.py

from django.shortcuts import render,HttpResponse,reverse
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值