【python】Django系列Day02--Django项目配置文件和路由

     阅读:29

🙋作者:爱编程的小贤
⛳知识点:Django–配置和路由
🥇:每天学一点,早日成大佬

👊前言

💎 💎 💎今天我们进入Django第二部分的学习啦!!! 🚀 🚀 🚀
如果你看完感觉对你有帮助,,,欢迎给个三连哦💗!!!您的支持是我创作的动力。🌹 🌹 🌹 🌹 🌹 🌹 感谢感谢!!!😘😘😘


🌷一、项目配置文件说明

下面代码看的更直观清楚!!!

在这里插入图片描述

"""
Django settings for FirstPro project.

Generated by 'django-admin startproject' using Django 3.2.6.

For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# 表示项目的根目录
print(BASE_DIR)
# 当debug为True的时候,会有两个线程来对配置文件进行管理,一个用于监控配置文件是否有变动
# 另一个用于将配置文件加载到项目之中,也就是服务于开发人员


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ''
# 加密盐,可修改为自己的盐但不要泄露

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True    # 当其为True的时候表示项目处于开发模式,在开发模式下就可以通过浏览器看到错误信息
# 当其为Flase时,表示项目处于生产模式,即已上线,前端看不到后端的接口以及相关的错误信息

ALLOWED_HOSTS = ["*"]   # 表示允许列表中的元素,也就是域名,允许其能够访问到后端服务器


# Application definition

# 子应用的注册
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'firstapp',     # 子应用注册     两种方式:1.直接将子应用名进行注册
    # 'firstapp.apps.FirstappConfig',   # 2. 通过子应用中的apps文件中的子应用的配置类进注册
]

# 中间件的注册
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 = 'FirstPro.urls'  # 根路由的位置,从项目根目录开始

TEMPLATES = [   # 模板的配置,T
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        '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 = 'FirstPro.wsgi.application'  # 指定wsgi服务的启动


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {   # 数据库的配置
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.2/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/3.2/topics/i18n/

LANGUAGE_CODE = 'zh-hans'     # 语言控制

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = False
# 当其值为True时表示项目使用的时区为django默认时区,即西八区,比北京时间要多8个小时
# 当其为False时,表示允许使用当前修改后的时区。


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'     # 静态文件的访问路径,默认就是static,可自行修改,但是不建议修改为其他,就默认的static
# 因为django底层封装好的模板它再进行查找的时候是找的static而不会去找自己重新定义的这个url

# 添加静态文件在项目中的查找路径,当debug为True会自动开启一个静态文件的访问路径的配置,但是当DEBUG为False的时候就会关闭此配置,所以就需要我们自行去配置静态文件的访问路由
STATICFILES_DIRS = [
  
    os.path.join(BASE_DIR, 'static'),
]

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'


🌷二、静态文件的配置

1.什么是静态文件

静态文件主要是指那些普通的文本文件或html或者想html的没有任何后台动作的jsp,asp,php页面文件。

2.静态文件的特点

它们的特点就是:只有文本或图片,且它们不会通过后台的控制来更改的元素。如果可以由后台控制的,就不属于静态文件了。所以,一般的静态文件内容是固定的文本或图片。如果jsp页面中包含了像<%—java代码—%>等后台脚本,那么该jsp页面就不是静态文本。

3.如何加载静态文件

**1.**首先确保django.contrib.staticfiles已经添加到settings.INSTALLED_APPS中。
**2.**确保settings.py中设置了STATIC_URL。 (注意:以上两条正常情况下都是在创建Django项目的时候就自动给我们弄好了的,只要我们没有去改动它 就不用管。)

在这里插入图片描述
在这里插入图片描述

**3.**在已经安装了的app下创建一个文件夹叫做static,
然后再在这个static文件夹下创建一个当前app的名 字的文件夹,
再把静态文件放到这个文件夹下。
例如app叫firstapp,有一个静态文件叫做wyz1.jpg,
那么路径为firstapp/static/firstapp/wyz1.jpg。
为什么在app下创建一个static文件夹,还需要在这个static下创建一个同app名字的文件夹呢?
原因是如果直接把静态文件放在static文件夹下,那么在模板加载静态文件的时候就是使用wyz1.jpg,
如果在多个app之间有同名的静态文件,这时候可能就会产生混淆。
而在static文件夹下加了一个同名的app文件夹,在模板中加载的时候就是使用app/wyz1.jpg,这样就可以避免产生混淆。)
注意:文件夹名字必须为static。

在这里插入图片描述

**4.**如果有一些静态文件是不和任何app挂钩的。即不再任何一个app的目录下。那么可以在setiings.py中添
加STATICFILES_DIRS,以后DTL就会在这个列表的路径中查找静态文件。例如我们在manage.py的同级目录下新建一个static的文件夹。然后在settings.py中添加STATICFILES_DIRS:
STATICFILES_DIRS = [ os.path.join(BASE_DIR,“static”) ]

在这里插入图片描述
在这里插入图片描述

🌷三、路由的使用

1.django解析路由的流程

在这里插入图片描述

2.概述

URL路由在Django项目中的体现就是urls.py文件,这个文件可以有很多个,但绝对不会在同一目录下。
实际上Django提倡项目有多个根目录urls.py,各app下分别有自己的一个urls.py,既集中又分治,是 一种解耦的模式。
随便新建一个Django项目,默认会为我们创建个/project_name/urls.py文件,并且自动包含下面内容,这就为项目的根URL:

"""
dj_test URL Configuration 
The `urlpatterns` list routes URLs to views. For more information please see: 
https://docs.djangoproject.com/en/2.0/topics/http/urls/ 
Examples: 
Function views 
1. Add an import: from my_app import views 
2. Add a URL to urlpatterns: path('', views.home, name='home') 

Class-based views 
3. Add an import: from other_app.views import Home 
4. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 

Including another URLconf 
5. Import the include() function: from django.urls import include, path 
6. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin 
from django.urls import path
urlpatterns = [
	 path('admin/', admin.site.urls), 
]

2.1 根路由中的admin管理页面

使用python manage.py createsuperuser命令来创建超级管理员 先执行python manage.py migrate命令

3.Django是如何处理请求的

当用户请求一个页面时,Django根据下面的逻辑执行操作:

  1. 决定要使用的根URLconf模块。通常,这是ROOT_URLCONF设置的值,但是如果传入的 HttpResponse对象具有urlconf属性(由中间件设置),则其值将被用于代替ROOT_URLCONF设
    置。也就是说可以自定义项目入口url是哪个文件。
  2. 加载该模块并寻找可用的urlpatterns。它是django.urls.path()或者django.urls.re_path()实例的一个列表。
  3. 依次匹配每个URL模式,在与请求的URL相匹配的第一个模式停下来。也就是说,url匹配是从上 往下的短路操作,所以url在列表中的位置非常关键。
  4. 导入并调用匹配航中给定的视图,该视图是一个简单的Python函数(称为视图函数)或基于类的 视图。视图将获得如下参数:
  5. 一个HttpResponse实例
  6. 如果匹配的表达式返回了未知名的组,那么匹配的内容将作为位置参数提供给视图。
  7. 关键字参数由表达式匹配的命名组组成,但是可以被django.urls.path()的可选参数kwargs覆盖。
  8. 如果没有匹配到任何表达式,或者过程中抛出异常,将调用一个适当的错误处理视图(比如403, 比如无任何反应)

Ps:

  1. urlpatterns是个列表,每个元素都是path()或re_path()的实例;

  2. 要捕获一段url中的值,需要用尖括号,而不是之前的圆括号;

  3. 可以转换捕获到的值为指定类型,默认情况下,捕获到的结果保存为字符串类型,不包含’/'这个特 殊字符;

  4. 匹配模式的最开头不需要添加’/‘,因为默认情况下,每个url都带一个最前面的’/',既然大家都有的 部分,就没必要浪费时间特别写一个。

  5. 每个匹配模式都建议以斜杠结尾

4.path转换器

默认情况下,Django内置下面的路径转换器: 路径传参:如果想要实现在url路径中放参数,就要用到路径传参。在定义路由条目时接收路径参数。

  • str:匹配任何非空字符串,但不含斜杠’/',如果你没有专门指定转换器,默认使用该转换器
  • int:匹配0和正整数,返回一个int类型
  • slug:可理解为注释、后缀、附属等概念,是url拖在 最后的一部分解释性字符。该转换器匹配任何ASCII字符以及连接符和下划线,比如building-your-lst-django-site;
  • uuid:匹配一个uuid格式的对象。为了防止冲突,规定必须使用破折号,所有字母必须小写,例如075194d3-6885-417e-a8a8-6c931e272f00。返回一个UUID对象;
  • path:匹配任何非空字符串,重点是可以包含路径分隔符’/'。这个转换器可以帮助你匹配整个url而不是一段一段的url字符串。要区分path转换器和path()方法。

5.自定义path转换器

对于更复杂的匹配需求,可能就需要自定义自己的path转换器。 path转换器其实就是一个类,包含下面的成员和属性:

  • 类属性regex:一个字符串形式的正则表达式属性;
  • to_python(self, value)方法:一个用来将匹配到的字符串转换为 你想要的数据类型,并传递给视图函数。如果转换失败,它必须弹出ValueError异常;
  • to_url(self, value)方法:将Python数据类型转换为一段url的方法,上面方法的反向操作。如果转换失败,也会弹出ValueError异常。

6.使用正则表达式

re_path()方法:与path()方法不同的在于三点:

  • 捕获URL中的参数使用的是正则捕获,语法为(?P< name >pattern),其中name是组名,pattern是要匹配 的模式。
  • year中匹配不到非四位数字,这是正则表达式决定的。
  • 传递给视图的所有参数都是字符串类型。而不像path()方法中可以指定转换成某种类型。在视图中 接收参数时一定小心。

7.匹配部分

请求的url被看做是一个普通的python字符串,URLconf在其上查找并匹配。进行匹配时将不包括GET或POST请求方式的参数以及域名

例如,
在 https://www.example.com/myapp/ 的请求中,URLconf将查找 myapp/ 。
在 https://www.example.com/myapp/?page=3 的请求中,URLconf也将查找 myapp/ 。
URLconf不检查使用何种HTTP请求方法,所有请求方法POST、GET、HEAD等都将路由到同一个URL的同一个视图。在视图中,才根据具体请求方法的不同进行不同的处理。

8. 指定视图参数的默认值

如下例:

from django.urls import path 
from . import views 
urlpatterns = [ 
	path('blog/', views.page), 
	path('blog/page<int:num>/', views.page), 
]
# 视图 (blog/views.py) 
def page(request, num=1): 
	# Output the appropriate page of blog entries, according to num. 
	...

如上述例子,两个URL模式只想同一个视图views.page。但是第一个模式不会从URL中捕获任何职。如果第一个模式匹配,page()函数将使用num参数的默认值’1’。如果第二个模式匹配,page()将使用捕获的num值。

🌷四、路由转发

通常,我们会在每个app里,各自创建一个urls.py路由模块,然后从根路由出发,将app所属的url请求,全部转发到响应的urls.py中。

例如,如下是Django网站本身的URLconf节选。它包含许多其他URLconf:

from django.urls import include, path 
urlpatterns = [ 
	# ... 省略... 
	path('community/', include('aggregator.urls')), 
	path('contact/', include('contact.urls')), 
	# ... 省略 ... 
]

路由转发使用的是include()方法,需要提前导入。 它的参数是转发目的地路径的字符串,路径以圆点分割。
每当Django遇到include()时,它会去掉URL中匹配的部分并将剩下的字符串发送给include的URLconf做进一步处理,也就是转发到二级路由去。
目的地URLconf会收到来自父URLconf捕获的所有参数,看下面的例子:

# In settings/urls/main.py 
from django.urls import include, path 
urlpatterns = [ 
	path('<username>/blog/', include('foo.urls.blog')), 
]

# In foo/urls/blog.py 
from django.urls import path 
from . import views
urlpatterns = [
	path('', views.blog.index), 
	path('archive/', views.blog.archive), 
]

在上面的例子中,捕获的"username"变量将被传递给include()指向的URLconf,再进一步传递给对应 的视图

1.向视图传递额外参数

URLconfs具有一个hook,允许传递一个Python字典作为额外的关键字参数给视图函数。如下:

from django.urls import path 
from . import views 
urlpatterns = [ 
	path('blog/<int:year>/', views.year_archive, {'foo': 'bar'}), 
]

在上面的例子中,对于 /blog/2005/ 请求,Django将调用views.year_archive(request,year=‘2005’,foo=‘bar’)。理论上,你可以在这个字典里传递任何你想要的传递的东西。但是要注意,URL模式捕获的命名关键字参数和在字典中传递的额外参数有可能具有相同的名称,这会发生冲突,将使用字典里的参数来替代捕捉的参数。

2.传递额外的参数给include()

类似上面,也可以传递额外的参数给include()。参数会传递给include指向的urlconf中的每一行。

例如,下面两种URLconf配置方式在功能上完全相同:
配置一:

# main.py 
from django.urls import include, path 
urlpatterns = [ 
	path('blog/', include('inner'), {'blog_id': 3}), 
]

# inner.py 
from django.urls import path 
from mysite import views 
urlpatterns = [ 
	path('archive/', views.archive), path('about/', views.about), 
]

配置二:

# main.py 
from django.urls import include, path 
from mysite import views 
urlpatterns = [ 
	path('blog/', include('inner')), 
]


# inner.py 
from django.urls import path 
urlpatterns = [ 
	path('archive/', views.archive, {'blog_id': 3}), 
	path('about/', views.about, {'blog_id': 3}), 
]

注意,只有当你确定被include的URLconf中的每个视图都接收你传递给它们的额外的参数时才有意义,否则其中一个以上视图不接收该参数都将导致错误异常。

🌷五、url命名与reverse逆向

1.路由命名

在定义路由时,可以为路由命名,方便查找特定视图的具体路径信息。

  1. 在使用include函数定义路由时,可以使用namespace参数定义路由的命名空间。如:
url(r'^users/',include('users.url',namespace='users'))

命名空间表示,凡是users.urls中定义的路由,均属于namespace指明的users名下。
命名空间的作用:避免不同应用中的路由使用了相同的名字发生冲突,使用命名空间区别开。

  1. 在定义普通路由时,可以使用name参数知名路由的名字。如:
urlpatterns = [ 
	url(r'^index/$',views.index,name='index') 
]

2. reverse逆向解析

  1. reverse的作用

reverse的主要作用是将提取的网址进行按照要求的替换,计算得到响应所需要的新的网址的功能,只要对应的url的name不变,就不用改变代码中的网址。

  • 对于未指明namespace的,reverse(路由name)
  • 对于指明namespace的,reverse(命名空间namespace:路由name)
url = reverse('users:index')  # 反解析:根据路由名称 index,返回 /users/index/
print(url)

🌷总结

Django的配置文件和路由我们就讲完啦!!!!👍👍👍 如果有帮到你欢迎给个三连支持一下哦❤️ ❤️ ❤️
如果有哪些需要修改的地方欢迎指正啦!!!一起加油👏👏👏