4 Django 路由分发 名称空间 伪静态 虚拟环境 版本区别 视图层

Django

1 路由分发

django中每一个app都可以拥有自己的templates文件夹、static文件夹以及urls.py。

  1. 基于路由分发,django项目可以进行多人分组开发,每个人只编写自己的app。
    整合app时,可以将所有app全部拷贝到一个新的django项目中,然后在配置文件settings.py中注册所有的app,再利用路由分发的特点在总路由中将所有的app整合起来。
  2. 当一个django项目的项目文件夹下的总路由urls.py中的路由url特别多时,总路由的代码非常冗余,不便于维护,此时可以通过路由分发来减轻总路由的压力。
    利用路由分发,总路由不再处理请求路由与视图函数的直接对应关系,而是做分发处理,识别当前的请求url是属于哪个应用的,再分发给对应的应用去处理。

在app的文件夹中新建urls.py。

app01 urls.py

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

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

app02 urls.py

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

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

路由分发关键字 include

总路由 urls.py

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

from app01 import urls as app01_urls  # 起别名
from app02 import urls as app02_urls

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    
    # 如果请求url是以app01开头,就交给app01处理。
    url(r'^app01/', include(app01_urls)),
    
    # 如果请求url是以app02开头,就交给app02处理。
    url(r'^app02/', include(app02_urls)),
]

当访问127.0.0.1:8080/app01/test/时,请求urlapp01/test/与总路由中的r'^app01/'实现匹配,因此交给app01处理,请求url后端的test/与app01中的子路由r'^test/'实现匹配,执行相应的视图函数。

总路由 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')),
]

注意,总路由中的url的正则表达式不要使用$,否则就会在$处停止匹配,即无法去各个app中继续匹配。

2 名称空间

对于反向解析,不同的app中可能为路由匹配起了相同的别名。

app01 urls.py

urlpatterns = [
    url(r'^test/', views.func_test, name='test_name'),
]

app02 urls.py

urlpatterns = [
    url(r'^test/', views.func_test, name='test_name'),
]

一般反向解析是没有办法自动识别前缀的。

2.1 名称空间

可以通过在总路由中设置名称空间来解决反向解析中别名冲突的问题。

总路由 urls.py

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

反向解析

app01 views,py

def func_test(request):
	reverse('app01:func_test')

app02 views,py

def func_test(request):
	reverse('app02:func_test')

test.html

{% url 'app01:func_test' %}
{% url 'app02:func_test' %}
2.2 为别名添加app名的前缀

只要保证不同的app中的路由匹配的别名不冲突,就没有必要使用名称空间了。

规则:
app中为路由匹配起别名时需要添加app名的前缀

app01 urls.py

urlpatterns = [
    url(r'^test/', views.func_test, name='app01_test_name'),
]

app02 urls.py

urlpatterns = [
    url(r'^test/', views.func_test, name='app02_test_name'),
]

3 伪静态

  1. 静态网页,html代码生成后,页面的内容和显示效果就基本上不会发生变化了,除非修改页面代码。
    静态网页有一个固定的URL,其后缀一般是.html,而且一般不含有问号。
  2. 动态网页,在不修改页面代码的前提下,页面显示的内容可以随着时间、环境或者数据库操作的结果而发生改变。

伪静态,是指将一个动态网页伪装成静态网页。
目的:增加本网站的seo查询力度,增加搜索引擎收录本网页的概率。

SEO (Search Engine Optimization),搜索引擎优化,利用搜索引擎的规则提高网站在相关搜索引擎内的自然排名。

静态网页一般不会经常修改,因此搜索引擎一般会优先收录静态网页。

urlpatterns = [
    url(r'^test.html', views.func_test, name='app01_test_name'),
]

4 虚拟环境

4.1 介绍

正常开发中会为每个项目开设一个项目独有的解释器环境,该环境中只安装该项目使用的模块,用不到的模块一概不装。

虚拟环境
创建一个虚拟环境就相当于重新下载了一个纯净的python解释器。
虚拟环境是需要消耗硬盘空间的,因此不要创建太多虚拟环境。

4.2 requirements.txt

不同的项目可能使用不同的模块,即使模块相同,模块版本也可能不同。
开发中会为每一个项目单独配备一个requirements.txt文件,其内部包含了该项目所需的所有模块及版本,
使用requirements.txt文件可以在新环境上快速构建项目所需的运行环境依赖模块,便于配置生产环境。

虚拟环境 生成requirements.txt
方法1

pip freeze > requirements.txt

方法2 pipreqs模块

# 安装pipreqs模块
pip install pipreqs
# 在当前目录生成requirements.txt
pipreqs . --encoding=utf8 --force

安装模块

pip install -r requirements.txt
4.3 使用pycharm创建虚拟环境

在pycharm中,新建项目,选择Virtualenv。
在这里插入图片描述
选项说明

  1. Inherit global site-packages
    新环境是否需要继承本机中已存在环境的所有模块,如果需要纯净的虚拟环境就不要勾选。
  2. Make available to all projects
    新创建的环境是否需要被所有项目使用,建议勾选。

如果项目中存在venv文件夹,说明该项目正在使用虚拟环境。

5 django版本区别

5.1 url,path和re_path
  1. django 1.X中,
    路由层使用url方法,url方法的第一个参数支持正则;
  2. django 2.X 和 3.X中,
    路由层一般使用path方法;
    path方法的第一个参数不支持正则,即精准匹配,写什么就匹配什么;
    路由层也可以使用re_path方法。
    re_path方法的第一个参数支持正则,相当于django 1.X中的url方法。

urls.py

from django.urls import path, re_path

urlpatterns = [	
	re_path(r'^index/', index),
]

补充,也可以在django 2.X 和 3.X中使用url,但不推荐。

from django.conf.urls import url

urlpatterns = [	
	url(r'^index/', index),
]
5.2 path支持五种转换器

path方法的内部支持五种转换器。
示例,访问http://127.0.0.1:8080/index/123

views.py

# 以关键字参数的方式接收路由参数。
def index(request, id):
	print(id, type(id))  # 123, <class 'int'>
	return HttpResponse('index')

urls.py

from django.urls import path

urlpatterns = [	
	path('index/<int:id>/', index),
	# 将第二个路由参数转换成整形,再以关键字参数的形式传给对应的视图函数。
]
str:匹配除了路径分隔符(/)之外的非空字符串,默认的形式;
int:匹配正整数,包含0;
slug:匹配字母、数字以及横杠、下划线组成的字符串;
uuid:匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00;
path:匹配任何非空字符串,包含了路径分隔符(/)。
5.3 path支持自定义转换器
class MonthConverter:
    regex='\d{2}'  # 属性名必须为regex

    def to_python(self, value):
        return int(value)

    def to_url(self, value):
        return value  # 匹配的regex是两个数字,返回的结果也必须是两个数字
from django.urls import path,register_converter
from app01.path_converts import MonthConverter
from app01 import views

# 先注册转换器
register_converter(MonthConverter, 'mon')

urlpatterns = [
    path('articles/<int:year>/<mon:month>/<slug:other>/', views.article_detail, name='aaa'),
]
5.4 级联更新和级联删除

模型层中,django 1.X默认是级联更新和级联删除;
django 2.X 和 3.X 中需要手动配置参数来实现级联更新和级联删除。

# django 1.X
models.ForeignKey(to='Publish')

# django 2.X 和 3.X
models.ForeignKey(
	to='Publish',
	on_update=models.CASCADE,
	on_delete=models.CASCADE
)

6 视图层

6.1 视图层的三板斧
HttpResponse
返回字符串类型

render
返回html页面,支持为html页面传值

redirect
重定向

视图函数必须返回一个HttpResponse对象。

shortcuts.py

def render(request, ...):
	...
	return HttpResponse(content, content_type, status)

def redirect(to, *args, **kwargs):
	if kwargs.pop('permanent', False):
        redirect_class = HttpResponsePermanentRedirect
    else:
        redirect_class = HttpResponseRedirect
	return redirect_class(resolve_url(to, *args, **kwargs))

# 类HttpResponsePermanentRedirect和类HttpResponseRedirect都是类HttpResponse的子类。

render如何为http页面传值

views.py

def index(request):
	from django.template import Template, Context
    res = Template('<h1>{{ user }}</h1>')
    con = Context({'user': {'username': 'Tom', 'password': 123}})
    # 将Template和Context结合起来。
    ret = res.render(con)
    print(ret)  # <h1>{&#39;username&#39;: &#39;Tom&#39;, &#39;password&#39;: 123}</h1>
    return HttpResponse(ret)
6.2 JsonResponse对象

json格式,用于跨语言传输数据,一般前后端数据交互使用json进行过渡。

6.2.1 使用json模块

view.py

def index(request):
    import json

    user_dict = {'username': '刘翠英', 'password': 123}
    json_str = json.dumps(user_dict, ensure_ascii=False)  # 默认ensure_ascii=True,json.dumps序列化时对中文默认使用的ascii编码,需要指定为False。
    return HttpResponse(json_str)
6.2.2 使用JsonResponse对象

字典序列化

from django.http import JsonResponse

def index(request):
    user_dict = {'username': '刘翠英', 'password': 123}
    return JsonResponse(user_dict)  # {"username": "\u5218\u7fe0\u82f1", "password": 123}
from django.http import JsonResponse

def index(request):
    user_dict = {'username': '刘翠英', 'password': 123}
    return JsonResponse(user_dict, json_dumps_params={'ensure_ascii': False})

列表序列化
注意:默认只能对字典进行序列化,对于其它数据类型需要修改safe参数为False。

from django.http import JsonResponse

def index(request):
    user_list = ['刘翠英', '马永强', '谢广坤',]
    # 默认只能对字典进行序列化,对于其它数据类型需要修改safe参数。
    return JsonResponse(user_list, json_dumps_params={'ensure_ascii': False})  # 报错
TypeError at /index/
In order to allow non-dict objects to be serialized set the safe parameter to False.
from django.http import JsonResponse

def index(request):
    user_list = ['刘翠英', '马永强', '谢广坤',]
    return JsonResponse(user_list, json_dumps_params={'ensure_ascii': False}, safe=False)
6.3 form表单上传文件

上传文件,form标签要求:

  1. method指定为post;
  2. enctype指定为multipart/formdata。
def upload_file(request):
    if request.method == 'POST':
    	# 获取文件数据
        print(request.FILES)  # <MultiValueDict: {'file': [<InMemoryUploadedFile: 0.jpg (image/jpeg)>]}>
        
        # 文件对象
        file_obj = request.FILES.get('file')  
        print(file_obj.name)  # 0.jpg
    
        with open(file_obj.name,'wb') as f:
            for line in file_obj.chunks():  # 推荐使用chunks方法。
                f.write(line)
    return render(request,'form.html')
6.4 request对象方法总结
方法介绍
request.method获取请求方法,GET/POST
request.POST返回querydict对象,包含通过POST请求提交的普通键值对数据,不包括文件。
request.GET返回querydict对象,包含所有GET请求参数。
request.FILES返回querydict对象,包含所有上传的文件。
request.body获取http请求主体,二进制格式。
request.path请求页面的路由,不包括协议以及域名,即相对于网站根目录的路径。
request.path_info在某些Web服务器配置下,主机名后的URL部分被分成脚本前缀部分和路径信息部分。path_info属性始终包含路径信息部分,不论使用的Web 服务器是。使用path_info代替path属性可以让代码在测试和开发环境中更容易进行切换。例如,如果应用的WSGIScriptAlias 设置为 “/minfo”,那么当 path 是"/minfo/music/bands/the_beatles/" 时,path_info 将是"/music/bands/the_beatles/"。
request.get_full_path()返回完整路径,包括问号后面的参数。
6.5 FBV 与 CBV

视图函数广义上既可以是函数也可以是类。

  1. FBV
    Function Base Views,基于函数的视图,
    在视图中使用函数处理请求。
def index(request):
    return HttpResponse('index')
  1. CBV
    Class Base Views,基于类的视图,
    在视图中使用类处理请求。

urls.py

url(r'^login/', views.MyLogin.as_view())  # as_view()注意要加括号。

views.py 处理业务逻辑的视图函数,形参中一般都会包括request

from django.views import View

class MyLogin(View):
	def get(self, request):
        return render(request, 'form.html')

	def post(self, request):
        return HttpResponse('post方法')

CBV的路由能够直接根据请求方式找到并执行对应的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Django中,include函数可以用于将某个url模式文件的路径包含到主url模式文件中,实现路由分发和管理。通过include函数,可以将不同部分的路由分别配置在不同的文件中,使得整个项目结构更加清晰和易于维护。在主url模式文件中,只需引入包含其他路由的文件路径即可。例如:url(r'^users/', include('users.urls')),就将指向"/users/"路径请求的路由指向了内部的users.urls文件。 ### 回答2: Django路由分发是指将网站请求分发给不同的视图函数或者应用程序。在Django中,路由分发可以使用include()函数实现。 include()函数允许将URL模式从其他模块导入到主URLConf中。这样,就可以把路由分发到其他应用程序或模块中去处理。在导入其他模块时,需要使用模块名和应用程序名称来指定路由。 当使用include()函数时,URLConf必须返回一个实例化的URLConf,而不能是一个URL模式。这个实例化的URLConf对象也可以是一个字符串列表,包含其他应用程序中的URL模式名称使用include()函数时,需要按照一定的模式来指定URLConf对象的路径。一个通用的格式是:`include(pattern_list, namespace=None)`,其中pattern_list是一个URLConf模块或者URL模式列表,namespace是一个可选的命名空间参数。 在使用include()函数时,需要考虑一些细节问题。首先,应该使用`r''`来表示正则表达式模式,这样可以确保正确的字符转义。其次,在使用namespace命名空间时,应该使用别名来避免重复。最后,在定义URLConf对象时,应该注意匹配所有可能的URL路径,以便覆盖所有的路由请求。 总之,Django路由分发(include)是一个非常灵活和方便的功能,可以帮助我们快速地将网站请求分发给不同的应用程序和模块,从而实现完整的网站架构。 ### 回答3: Django框架是一个基于MTV模式的Web应用程序开发框架,为开发人员提供了诸多便利。其中,路由分发Django框架中重要的一环,负责将请求分配到相应的视图函数中。而include函数在路由分发中发挥着重要作用。 include函数实际上是一种路由分发方式,其作用是将一个应用程序中的URL映射添加到一个项目中。在Django应用程序中,一般情况下需要将所有的URL映射添加到一个名为urls.py的文件中。在这个文件中,我们可以定义Django应用程序中的URL与其相应的视图函数之间的映射关系。 当应用程序中的URL数量增加后,为了更好的管理和维护,我们可以将URL映射按照不同的业务功能模块进行分组。这个时候,include函数就派上用场了。可以在项目中的urls.py文件中使用include函数,将某个应用程序中的urls.py文件引入到项目中。具体操作如下: 1. 在项目的urls.py文件中引入include函数,例如:`from django.urls import include, path` 2. 在项目的urls.py文件中配置一个URL模式,例如:`path('app/', include('myapp.urls'))` 3. 在应用程序中的urls.py文件中配置URL模式 使用include函数可以将URL模式按照不同的业务模块进行划分,减轻代码维护的复杂度。同时,在应用程序中使用include函数可以将应用程序抽象成一个独立的模块,方便进行重用和共享。include函数简化了URL配置的结构,提高了代码的可阅读性和可重用性。 总之,include函数是Django路由分发中非常实用的工具,可以帮助我们更好地组织和管理URL模式,提高开发效率和代码质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值