A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 旖旎醉秋光 初级黑马   /  2019-5-16 19:26  /  1324 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

# 4.Django

#### 1.web工作流程

![1557817374112](assets/1557817374112.png)

2.mvt和mvc的区别

![1557818914560](assets/1557818914560.png)

- M全拼为Model,主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。
- V全拼为View,用于封装结果,生成页面展示的html内容。
- C全拼为Controller,用于接收请求,处理业务逻辑,与Model和View交互,返回结果。
- ![1557819145918](assets/1557819145918.png)



![1557819163646](assets/1557819163646.png)

![1557819188682](assets/1557819188682.png)

#### 2.环境安装

##### 1.创建虚拟环境

虚拟环境的作用:
作用 : 虚拟环境可以搭建独立的python运行环境, 使得单个项目的运行环境与其它项目互不影响.

所有的虚拟环境都位于/home/下的隐藏目录.virtualenvs下

1. 创建虚拟环境

创建虚拟环境之前先看一下现有的虚拟环境  workon

```shell
mkvirtualenv django_py3_1.11 -p python3
```

注意需要联网

2. 安装Django

使用django 1.11.11版本,注意需要联网

```shell
pip install django==1.11.11
```

需要在虚拟环境下进行安装 否则会查找不到

3. 复习虚拟环境和pip的命令

```shell
# 虚拟环境
mkvirtualenv  # 创建虚拟环境
rmvirtualenv  # 删除虚拟环境
workon  # 进入虚拟环境、查看所有虚拟环境
deactivate  # 退出虚拟环境

# pip
pip install  # 安装依赖包
pip uninstall  # 卸载依赖包
pip list  # 查看已安装的依赖库
一般使用pip3
```

##### 2.创建工程

1.创建工程文件夹

```shell
django-admin startproject 工程名称
```

执行后,会多出一个新目录名为demo,此即为新创建的工程目录。

![1557821571326](assets/1557821571326.png)

- 与项目同名的目录,此处为demo。
- **settings.py** 是项目的整体配置文件。
- **urls.py** 是项目的URL配置文件。 配置路由
- **wsgi.py** 是项目与WSGI兼容的Web服务器入口。
- **manage.py** 是项目管理文件,通过它管理项目。

##### 3.测试运行

显示端口被占用:sudo fuser -k 8000/tcp  杀掉端口为8000的服务

运行服务器命令如下:

```shell
python manage.py runserver ip:端口
或:
python manage.py runserver
```

- 默认地址为 http://127.0.0.1:8000/
- django默认工作在调式Debug模式下,如果增加、修改、删除文件,服务器会自动重启。
- 按ctrl+c停止服务器

##### 4.创建子程序

在Web应用中,通常有一些业务功能模块是在不同的项目中都可以复用的,故在开发中通常将工程项目拆分为不同的子功能模块,各功能模块间可以保持相对的独立,在其他工程项目中需要用到某个特定功能模块时,可以将该模块代码整体复制过去,达到复用。

###### 1.创建

创建子应用依然可以通过命令行执行,需要执行manage.py文件进行修改,**manage.py** 为上述创建工程时自动生成的管理文件。

```
python manage.py startapp 子应用名称
```

注意所有的应用都必须在虚拟环境中运行

生成结果:![1557822779188](assets/1557822779188.png)

- **admin.py** 文件跟网站的后台管理站点配置相关。
- **apps.py** 文件用于配置当前子应用的相关信息。应用配置文件 主文件中setting是配置文件
- **migrations** 目录用于存放数据库迁移历史文件。
- **models.py** 文件用户保存数据库模型类。
- **tests.py** 文件用于开发测试用例,编写单元测试。
- **views.py** 文件用于编写Web应用视图。

###### 2.注册和安装子程序

创建出来的子应用目录文件虽然被放到了工程项目目录中,但是django工程并不能立即直接使用该子应用,需要注册安装后才能使用。

在工程配置文件settings.py中,**INSTALLED_APPS**项保存了工程中已经注册安装的子应用,初始工程中的INSTALLED_APPS如下:

1.0版本之前需要在前面加根目录名 此处为demo

![1557823196294](assets/1557823196294.png)

注册安装一个子应用的方法,即是将子应用的配置信息文件apps.py中的Config类添加到INSTALLED_APPS列表中。

##### 5.创建视图

视图即可以通过url访问

Django的视图是定义在子应用的views.py中的。  

此处应用到了views的业务逻辑方面用法

1.在views中编写视图代码

views:

```python
from django.shortcuts import render
# 创建视图1. 导入响应报文函数
from django.http.response import HttpResponse

# 用于反推路径
from django.urls import reverse

# Create your views here.
# 创建视图函数在这里
# 这里是访问窗口后执行的函数 所以需要返回一个相应头
# 需要接收请求报文  必须接收 因为返回值的方法需要接收一个参数
def index(request):
        #作用1.接收请求报文
    #2.解析请求对象
    #3.model template的中间站
    #4.发送响应报文
    print(reverse('user:index'))
    #只能以此方式发送响应报文
    return HttpResponse('这里是来自李叔叔的1号响应报文')
```



2.urls配置路由

urls:

```python
from django.conf.urls import url

#此处为自定义模块  用于导入路由
from . import views

#创建视图2 设置路由  url路径可以使用正则表达式
urlpatterns = [
    url(r'^index/$', views.index, name='index'),
    url(r'^indextwo/$', views.indextwo, name='index')
]
```

1. 每个函数需要建立一个路由,路由需要和函数进行匹配
2. 导入函数地址时需要导入函数之前需要先导入views文件

3.总路由中添加子程序的路由

主应用urls:

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


urlpatterns = [
    url(r'^admin/', admin.site.urls),
   
    # 对于配置子应用的路由,需要使用include方法 (子路由路径)
    url(r'^user/',include('user.urls',namespace='user')),
    #todo  不能全匹配 因为这里只是有一部分信息  末尾不能加$
    url(r'^demorequest/',include('demorequest.urls',namespace="demorequest"))

    # 路由设置 第二种路由的写法 直接导入模块包
    # url(r'^user/',user.views.index)
]
```

- Include的两种导入方式

- - 1. 字符串方式:include(‘urls的路径’)’

- - 2. 导入包的形式:include(路径)

    From . import 路径名称  相对路径写法

##### 6 pycharm中环境的切换

![1558000519837](../../%E7%AC%94%E8%AE%B0/%E5%8D%95%E6%97%A5%E7%AC%94%E8%AE%B0django/assets/1558000519837.png)

- 设置该虚拟环境
- 路径为:/home/python/.virtualenvs/my_django_py3_1.11/bin/python3
- /home/python/.virtualenvs 这个是虚拟环境的路径
- ![1558000613258](../../%E7%AC%94%E8%AE%B0/%E5%8D%95%E6%97%A5%E7%AC%94%E8%AE%B0django/assets/1558000613258.png)

##### 7.pycharm中直接运行manger.py

由于本程序运行时需要使用命令行`python3 manger.py runstart`,所以在pycharm中无法直接运行 ,进而使用修改启动方法,让程序可以直接在pycharm中运行

![1558001197253](assets/1558001197253.png)

##### 8.git的使用

1. 进入文件根目录  使用口令  git init
2. pycharm需要重新启动一下  
3. 快捷键ctrl+k  可以commit

#### 3.配置、静态文件与路由

##### 1.路由说明

###### 1.路由的定义方式

1.每个子应用为了保持相对独立,可以在各个子应用中定义属于自己的urls.py来保存该应用的路由。然后用主路由文件包含各应用的子路由数据。

子路由中urls代码

```python
from django.conf.urls import url
#此处为自定义模块  用于导入路由
from . import views

#创建视图2 设置路由  url路径可以使用正则表达式
urlpatterns = [
    url(r'^index/', views.index)
]
```

主路由中url代码

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

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^user/',include('user.urls')),
]
```

2.将工程的全部路由信息都定义在主路由文件中,子应用不再设置urls.py。如:

```python
from django.conf.urls import url,include
from django.contrib import admin
import user.views

urlpatterns = [
    url(r'^admin/', admin.site.urls)
    # 路由设置 第二种路由的写法 直接导入模块包,根据相对路径书写
     url(r'^user/',user.views.index)
]
```

###### 2.路由解析的顺序

路由解析顺序是由上至下,有可能会使上面的路由屏蔽掉下面的路由,带来非预期结果。

案例:

同时设置2个响应函数 ,第一个函数名为index,第二个函数名为index2

url匹配时没有加后面的/%后缀,

匹配结果:会优先匹配前面的一个函数

###### 3.路由命名与reverse反解析(逆向)

1.路由的命名:

​        在(urls 主程序路由配置)使用include函数(即主页中)定义路由时,可以使用namespace参数定义路由的命名空间,

​        且在子程序的urls的路由配置中,可以使用name参数给路由命名

命名空间表示,凡是user.urls中定义的路由,均属于namespace指明的user名下。

**命名空间的作用:避免不同应用中的路由使用了相同的名字发生冲突,使用命名空间区别开。**

2.reverse反解析

使用reverse函数,可以根据路由名称,返回具体的路径

- 对于未指明namespace的,reverse(路由name)

- def index(request):

  ```
  print(reverse('user:index'))
  #只能以此方式发送响应报文
  return HttpResponse('这里是来自李叔叔的1号响应报文')
  ```

- 对于指明namespace的,reverse(命名空间namespace:路由name)

```
def index(request):

    print(reverse('index'))
    #只能以此方式发送响应报文
    return HttpResponse('这里是来自李叔叔的1号响应报文')
```

指定了spacename必须使用前面一种

反解析的应用:

- 对于类似注册 提交订单之后会返回网站的主页面,就可以通过反解析 根据spacename和name来动态关联主页,以后主页名称修改了也不会造成影响.

##### 2.配置文件

1.base_dir

当前工程的根目录,Django会依此来定位工程内的相关文件,我们也可以使用该参数来构造文件路径。

进行3次去掉文件名 返回目录的操作 即可获得最外层文件的绝对路径

![1557925690741](assets/1557925690741.png)

2.debug

```python
#设置是否调试模式 ,即生产模式需要把debug修改为False  注意大小写   这里是为了应对404页面

#SECURITY WARNING: don't run with debug turned on in production!

DEBUG = True
#You must set settings.ALLOWED_HOSTS if DEBUG is False.  设置了非调试模式必须设置允许的域名 一般设置为空 表示全部允许  即ALLOWED_HOSTS = [' ']
ALLOWED_HOSTS = []
```

3.Application definition 注册子应用

```python
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    #注册子应用  子应用中路径.apps.userConfig
    'user.apps.UserConfig',
]
```

ps:子应用的注册:命令行中输入:python manage.py startapp 子应用名称

4.本地化语言时区:

初始化的工程默认语言和时区为英语和UTC标准时区

```python
LANGUAGE_CODE = 'en-us'  # 语言
TIME_ZONE = 'UTC'  # 时区
```

将语言和时区修改为中国大陆信息

```python
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
```

调试模式的404页面

![1557924451841](assets/1557924451841.png)

非调试模式的404页面:

![1557925888630](assets/1557925888630.png)

##### 3.静态文件配置

项目中的CSS、图片、js都是静态文件。一般会将静态文件放到一个单独的目录中,以方便管理。在html页面中调用时,也需要指定静态文件的路径,Django中提供了一种解析的方式配置静态文件路径。静态文件可以放在项目根目录下,也可以放在应用的目录下,由于有些静态文件在项目中是通用的,所以推荐放在项目的根目录下,方便管理。

同样是在setting.py中配置的

```
# 静态文件CSS, JavaScript, Images
# STATIC_URL访问静态文件的URL前缀
STATIC_URL = '/static/'
#STATICFILES_DIRS=[] 存放查找静态文件的目录 接收的是list
#STATICFILES_DIRS=['static_files']
STATICFILES_DIRS=[os.path.join(BASE_DIR,'static_files')]
```

- STATICFILES_DIRS的值为['/home/python/Desktop/demo/static_files'] 绝对路径
- BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(`__file__`))),意思是 主文件的绝对路径
- os.path.join()函数用于路径拼接文件路径。
- - 会从第一个以”/”开头的参数开始拼接,之前的参数全部丢弃。
  - 以上一种情况为先。在上一种情况确保情况下,若出现”./”开头的参数,会从”./”开头的参数的上一个参数开始拼接。

静态文件夹可以有多个 如果多个文件夹中有同名的文件,按照STATICFILES_DIRS列表中的文件导入顺序寻找动态文件夹

以当前的设置访问静态文件的话   url为:172.0.0.1:8000/static/动态文件名

![1557926900821](assets/1557926900821.png)

#### 4.请求与响应

##### 1.请求对象传参 4种

###### 1.url请求路径传参  

**方法1:**

提取URL的特定部分,如资源路径为:/beijing/2018,可以在服务器端的路由中用正则表达式截取;

1. 在路由中设置匹配的正则表达式  此处以资源路径为/beijing/2018为例:

2. ```python
   urlpatterns = [
       #url路径中的/为路径自带的/
       # \d:匹配一个数字0-9   +:匹配前面的子表达式一次或多次。
       #[a-z]+ 匹配a-z  至少出现一次
       url(r'^index/(\d+)/([a-z]+)/', views.index,name='demorequest_index'),
   ]
   ```

3. 获取到该函数后,在视图函数中对其路径进行解析

4. 视图函数有默认的位置参数,第一个为request  格式为:

   - <WSGIRequest: GET '/demorequest/index/2008/beijing/'>

5. 资源中的第一部分 此题中为beijing

6. 以此类推 第二个为第二个/后的部分 为2018

7. 传递了几个参数就只能接收几个参数,多出了话会报错

**string{}.format(str):使用str代替{}   相当于一个占位符  %**

**方法2**

此方法从仅为正则表达式的不同,对正则表达式的的组进行命名, 命名和视图函数中的参数名一致,如果这样的话可以不用按照顺序传递参数

- **正则表达式给一个组中的数据取名:(?P<要取的名字>正则表达式)**

###### 2.查询字符串

形如key1=value1&key2=value2;

**查询参数的获取**:

1. request.GET(获取查询参数)  和请求方式无关 只是获取查询字符串的

```
  返回值为:<QueryDict: {'a': ['10','20'], 'b': ['2']}>
```

- 返回值是一个QueryDict对象

  - ```
    关于QueryDict对象:
    定义在django.http.QueryDict
    HttpRequest对象的属性GET、POST都是QueryDict类型的对象
    与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况
    ```

- 对于同一个key  可以赋予多个值,放在一个列表中

2. 对于单个查询参数的获取:

   - QueryDict对象.get(键)  可以获得键的值  如果值有多个,只返回最后一个

   - QueryDict对象.getlist(键) 可以获得键的值组成的列表 可以遍历出结果

   - ```python
     def findstring(request):
         result = request.GET
         print(result)
         key_a=result.getlist('a')
         print(key_a)
         return HttpResponse('这里是查询字符串函数返回的返回值')
     <<<['10']
     ```

     

解决postman问题

![1557935363212](assets/1557935363212.png)

###### 3.请求体传参

1.from-data(表单)数据类型

前端发送的表单类型的请求体数据,可以通过request.POST属性获取,返回QueryDict对象。

**重要:request.POST只能用来获取POST方式的请求体表单数据。**

```python
#请求头fromdata传参
def fromdata(request):
    #request.POST只能用来获取POST方式的请求体表单数据。
    result = request.POST
    print(result)
    value_b = result.get('b')
    print(value_b)
    value_a = result.getlist('a')
    print(value_a)

    return HttpResponse('fromdata传参')
```

使用post请求方式,同样返回的是一个QueryDict对象  但是需要使用.post来获取

获取表单中值的方法和之前的一个 get和getlist

###### postman的使用

![1557940671877](assets/1557940671877.png)

###### 4.非表单类型

Non-Form Data

此处以json字符串为例:

![1557940751119](assets/1557940751119.png)

首先要进行如此选择,才可以发送json数据

![1557941666835](assets/1557941666835.png)

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马