Django使用,MVC和MTV架构,配置settings.py文件,各种url写法,CBV和FBV,生命周期与中间件(各种详细的代码)

目录:

一. Web框架本质----socket

1、web框架本质

1. 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

2. 真实web框架一般会分为两部分:服务器程序和应用程序。

1)服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理

2)应用程序则负责具体的逻辑处理

2、WSGI(Web Server Gateway Interface)

1. 不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。

2. 这样,服务器程序就需要为不同的框架提供不同的支持,只有支持它的服务器才能被开发出的应用使用,这时就需要有一个标准

3. WSGI是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦。

3、使用socket创建一个简单web服务

使用socket创建一个简单web服务
  4、自定义Web框架

说明: 通过python标准库提供的wsgiref模块开发一个自己的Web框架

自定义web框架

二. MVC和MTV架构

1、MVC架构

  • MVC架构把一个完整的程序或者网站项目分成三个主要的组成部分,分别是Model模型,View视图,Controller控制器
  • 希望一个项目可以让内部数据的储存方式,外部的可见部分以及过程控制逻辑相互配合运行
  • 进一步简化项目复杂度,提高可扩充性,维护性,有助于不同成员之间的分工

2、MTV框架(Django)

  • 对于网站而言,网页服务器在接收到远程浏览器的请求的时候,不同的网址做出不同的响应
  • 有不同的链接方式其实就隐含了逻辑控制,因此很难严谨的将其定义为上述三个部分
  • 因此Django另外设计了MTV结构(Model,Template,View)。

3、MVC vs MTV

MVC:

  • MVC Model(数据库 ) View(模板文件) Controller(业务处理)
  • M( Model): 主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。
  • V( View): 用于封装结果,生成页面展示的html内容。
  • C(Controller): 用于接收请求,处理业务逻辑,与Model和View交互,返回结果。

MTV:

  • MTV Model(数据库) Template(模板文件) View( 业务处理)
  • M( Model): 与MVC中的M功能相同,负责和数据库交互,进行数据处理。
  • V( View): 与MVC中的C功能相同,接收请求,进行业务处理,返回应答。
  • T(Template): 与MVC中的V功能相同,负责封装构造要返回的html。

三. Django常用命令

1、安装Django

  • pip3 install django

2、创建Django工程

D:\>  django-admin startproject laoniu       //创建项目名称laoniu
                                        
D:\>  cd laoniu

D:\laoniu>  python manage.py runserver 127.0.0.1:8002       //运行laoniu即可用浏览器访问了

D:\laoniu>  python manage.py createsuperuser     //创建Django admin用户                      

3、创建app

  • python manage.py startapp app01 //创建子应用

4、迁移表&创建超级用户

迁移命令:

  • python manage.py makemigrations
  • python manage.py migrate

创建超级用户命令:

  • python manage.py createsuperuser

3.安装应用

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    #添加子应用
    'book.apps.BookConfig'
]

5.本地化

#设置中文
LANGUAGE_CODE = 'zh-Hans'
#亚洲上海时区
TIME_ZONE = 'Asia/Shanghai'

6.模板路径

  • 在应用同级目录下,创建templates 模板文件夹,

然后创建路径:

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',
            ],
        },
    },
]

7.项目中匹配urls

正则 : 路径只要不是admin/就算匹配成功。并包含到应用中的urls.py

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

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    #正则为:只要不是 admin/ 就算匹配成功
    url(r'^',include('book.urls'))
]

8.应用中匹配 urls.py

正则 : 路径中包含 booklist/,就调用视图中对应的 bookList 函数

from django.conf.urls import url
from book.views import bookList

urlpatterns = [

    # 匹配书籍列表信息的URL,调用对应的bookList视图
    url(r'^booklist/$',bookList)
]

9.准备视图

# 定义视图:提供书籍列表信息
def bookList(request):

    return HttpResponse('OK!')

10.开启服务器, 测试项目

# 进入项目文件中, 开启项目对应的服务器
python manage.py runserver

# 浏览器中输入网址
http://127.0.0.1:8000/booklist/

配置:

在settings.py中保存了数据库的连接配置信息,Django默认初始配置使用sqlite数据库。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

1.使用MySQL数据库首先需要安装驱动程序

2.在Django的工程同名子目录的__init__.py文件中添加如下语句

import pymysql

pymysql.install_as_MySQLdb()
  • 作用是让Django的ORM能以mysqldb的方式来调用PyMySQL。

3.修改DATABASES配置信息

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',  # 数据库主机
        'PORT': 3306,  # 数据库端口
        'USER': 'root',  # 数据库用户名
        'PASSWORD': 'mysql',  # 数据库用户密码
        'NAME': 'book'  # 数据库名字
    }
}

4.在MySQL中创建数据库

create database book charset=utf8;

11、执行python manage.py migrate无法创建表

  • 执行时报:No migrations to apply.

    • 进入数据库,找到django_migrations的表,删除该app名字对应的所有记录
    • python manage.py dbshell
    • delete from django_migrations where app=‘app01’;
  • 删除该app名字下的migrations下的除了__init__.py之外的文件。

  • 执行下面这两条命令:(在项目目录下)

    • python manage.py makemigrations
    • python manage.py migrate

注:如果个别app表依然无法建立可以在后面添加app名称:python manage.py makemigrations/migrate app01

12、“Column ‘last_login’ cannot be null”报错

mysql> SELECT * FROM django_migrations;

mysql> TRUNCATE TABLE django_migrations;

$ python manage.py migrate --fake-initial
Make sure this message appears: 0005_alter_user_last_login_null - [OK]

13、windows中杀死指定端口号进程

  • D:>netstat -aon|findstr “8000”
  • D:>taskkill /PID 12516 -t -f

四. 配置settings.py文件

1、配置模板的路径

TEMPLATES = [
    {
       'DIRS': [os.path.join(BASE_DIR,'templates')],
    },
]

2、 配置静态目录

#像ccs和js这些静态文件如果想要使用必须在这里配置路径
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'static'),
)

3、注释CSRF

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

4、修改settings.py中时区

修改settings.py中时区:

# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'

五. Django各种url写法

1、无正则匹配url (http://127.0.0.1:8000/index/?nid=1&pid=2)

urls.py:

urlpatterns = [
    url(r'^index/', views.index),
]

views.py:

from django.shortcuts import render

def index(request):
    print(request.GET.get('nid'))             # 1
    print(request.GET.get('pid'))             # 2
    return render(request,'index.html')

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="/index/?nid=1&pid=2"> url.py中不必用正则匹配 </a>
</body>
</html>

2、使用name构建自己想要的url

1. 使用name在前端和后端分别构建自己想要的url

urls.py中定义路由系统:

urlpatterns = [
    url(r'^index1/', views.index,name='indexname1'),
    url(r'^index2/(\d+)/(\d+)/', views.index,name='indexname2'),
    url(r'^index2/(?P<pid>\d+)/(?P<nid>\d+)/', views.index,name='indexname3'),
]

views.py中根据reverse模块构建url路径:

from django.shortcuts import render
from django.core.urlresolvers import reverse

def index(request,*args,**kwargs):
    url1 = reverse('indexname1')                                      # /index1/
    url2 = reverse('indexname2', args=(1,2,))                         # /index2/1/2/
    url3 = reverse('indexname3', kwargs={'pid': 11, "nid":22})        # /index2/11/22/
    return render(request,'index.html')

index.html中构建url路径:前端:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p><a href="{% url 'indexname1' %}">  http://127.0.0.1:8000/index/  </a></p>
    <p><a href="{% url 'indexname2' 1 2 %}">  http://127.0.0.1:8000/index2/1/2/  </a></p>
    <p><a href="{% url 'indexname3' 11 22 %}">  http://127.0.0.1:8000/index2/11/22/  </a></p>
</body>
</html>

2. 根据request.path中的绝对路径反解出url中的name名字

resolve_url_obj = resolve(request.path)    #request.path路径: /student/homework_detail/52
resolve_url_obj.url_name                   #从path中解析出url名字 url_name = homework_detail

3、Django路由分发 并使用name构建url路径

**作用:对URL路由关系进行命名, 以后可以根据此名称生成自己想要的URL **

/project/urls.py:

from django.conf.urls import url,include
from app01 import urls

urlpatterns = [
    url(r'^app01/', include("app01.urls", app_name='app01', namespace='app01')),
]

/app01/urls.py:

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

urlpatterns = [
    url(r'^index/$', views.index, name='index'),
]

views.py:

from django.shortcuts import render
def index(request):
    return render(request,'index.html')

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p> <a href="{% url "app01:index" %}">  http://127.0.0.1:8000/app01/index/</a></p>
</body>
</html>

六. Django的CBV和FBV

1、FBV(function base view):在views.py文件中使用函数

FBV写法:

def index(request):
    return render(request, 'index.html')

2、CBV(class base view):在views.py文件中使用类

  • dispatch是父类中用来反射的函数,找对应的函数(比对应函数先执行)
  • 比如你发送post请求就可以通过dispatch找到对应的post函数进行处理,get就会找到get函数处理

CBV:urls.py:

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

urlpatterns = [
    url(r'^home/',views.Home.as_view()), #as_view是指定调用view的as_view这个方法固定写法
]

CBV:views.py:

from django.shortcuts import HttpResponse

from django.views import View
class Home(View):
    '''使用CBV时必须要继承view父类'''
    def dispatch(self, request, *args, **kwargs):
        # 调用父类中的dispatch
        result = super(Home,self).dispatch(request, *args, **kwargs)
        # 使用result主动继承view父类,然后return就可以重写父类的dispath方法
        return result
    # 在这里使用get发来请求就会调用get方法,使用post发来请求就会调用post方法
    def get(self,request):
        print(request.method)
        return HttpResponse('get')

    def post(self,request):
        print(request.method,'POST')
        return HttpResponse('post')

CBC:指定某个视图函数不使用csrf验证:

from django.shortcuts import HttpResponse
from django.views import View
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt

class Home(View):
    '''使用CBV时必须要继承view父类'''
    @method_decorator(csrf_exempt)        # 指定Home这个视图函数不使用csrf
    def dispatch(self, request, *args, **kwargs):
        # 调用父类中的dispatch
        result = super(Home,self).dispatch(request, *args, **kwargs)
        # 使用result主动继承view父类,然后return就可以重写父类的dispath方法
        return result
    # 在这里使用get发来请求就会调用get方法,使用post发来请求就会调用post方法
    def get(self,request):
        print(request.method)
        return HttpResponse('get')

    def post(self,request):
        print(request.method,'POST')
        return HttpResponse('post')

七. 前后端交互:提交数据、提交文件

index.html提交数据:

<form action="/login/" method="post" enctype="multipart/form-data">
    <p>
        <input type="text" name="user" placeholder="用户名">
    </p>
    
    {# 1、单选框,返回单条数据的列表 #}
    <p>     
        男:<input type="radio" name="gender" value="1">
        女:<input type="radio" name="gender" value="2">
        张扬:<input type="radio" name="gender" value="3">
    </p>

    {# 2、多选框、返回多条数据列表 #}
    <p>     
        男:<input type="checkbox" name="favor" value="11">
        女:<input type="checkbox" name="favor" value="22">
        张扬:<input type="checkbox" name="favor" value="33">
    </p>

    {# 3、多选,返回多条数据的列表 #}
    <p>     
        <select name="city" multiple>
            <option value="bj">北京</option>
            <option value="sh">上海</option>
            <option value="gz">广州</option>
        </select>
    </p>

    {# 4、提交文件 #}
    <p><input type="file" name="fff"></p>
    <input type="submit" value="提交">
</form>

views.py获取数据:

def login(request):
    if request.method == 'GET':
        return render(request,'login.html')
    elif request.method == 'POST':
        v = request.POST.get('gender')      #1 获取单选框的value值
        v = request.POST.getlist('favor')   #2 获取多选框value:['11', '22', '33']
        v = request.POST.getlist('city')    #3 获取多选下拉菜单:['bj', 'sh', 'gz']
        print(v.name,type(v))


        #当服务器端取客户端发送来的数据,不会将数据一下拿过来而是一点点取(chunks就是文件分成的块)
        
        obj = request.FILES.get('fff')      #4 下面是获取客户端上传的文件(如:图片)
        import os
        file_path = os.path.join('upload',obj.name)
        f = open(file_path,mode='wb')
        for i in obj.chunks():
            f.write(i)
        f.close()

        return render(request,'login.html')

request获取数据方式:

# 1、request.POST
# 2、request.GET
# 3、request.FILES
# 4、request.getlist
# 5、request.method
# 6、request.path_info                   #获取当前url
# 7、request.body                        #自己获取数据
# 8、a = ‘中国’
    response = HttpResponse(a)
    response[“name”] = ‘alex’        #HttpResponse不仅可以在响应头中传字符串,也可以传键值对
    response.set_cookie()                #设置cookie实质也是向请求头中传入键值对

八. Django生命周期与中间件

1、中间件处理过程

1、首先客户端发起请求,会将请求交给settings.py中排在最前面的中间件

2、前面中间件收到请求会调用类中的process_request方法处理,然后交给下一个中间件的process_request函数

3、到达最后一个中间件的process_request函数处理后会到达url路由系统

4、然后从路由系统直接跳转到第一个中间件的process_view函数,依次向后面中间的process_view传递,最后到达views.py处理函数,获取网页中的数据

5、获取的数据会交给最后一个中间件的process_response方法处理,然后依次向前面的中间件process_response方法提交请求的内容,最后由最前面的中间件将请求数据返回到客户端

6、在任一中间件的process_request和process_view方法中有返回值就会直接返回给process_response

2、生命周期图解

在这里插入图片描述

3、Django生命周期请求过程

1.客户端访问

  • 客户端在浏览器中输入url路径访问指定网页

2. 请求发送给Django程序

1、首先会交给中间件,中间件处理后交给路由系统

2、路由系统

  • Django程序会到urls.py文件中找到对应请求的处理函数(视图函数)

3、视图函数

  • 视图函数会找到对应的html模板文件
  • 然后到数据库中取得数据替换html模板中的内容
  • 使用static中的js和css文件结合对html渲染
  • 最后Django将最终渲染后的html文件返回给中间件

4、中间件再调用process_response方法处理,最后交给用户

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值