2019独角兽企业重金招聘Python工程师标准>>>

自定义path转换器

其实就是写一个类,并包含下面的成员和属性:

类属性regex:一个字符串形式的正则表达式属性; to_python(self, value) 方法:一个用来将匹配到的字符串转换为你想要的那个数据类型,并传递给视图函数。如果转换失败,它必须弹出ValueError异常; to_url(self, value)方法:将Python数据类型转换为一段url的方法,上面方法的反向操作。 例如,新建一个converters.py文件,与urlconf同目录,写个下面的类:

class FourDigitYearConverter:regex = '[0-9]{4}'def to_python(self, value):return int(value)def to_url(self, value):return '%04d' % value

写完类后,在URLconf 中注册,并使用它,如下所示,注册了一个yyyy:

from django.urls import register_converter, pathfrom . import converters, viewsregister_converter(converters.FourDigitYearConverter, 'yyyy')urlpatterns = [path('articles/2003/', views.special_case_2003),path('articles/<yyyy:year>/', views.year_archive),...
]

使用正则表达式

from django.urls import path, re_pathfrom . import viewsurlpatterns = [path('articles/2003/', views.special_case_2003),re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),
]
与path()方法不同的在于两点:year中匹配不到10000等非四位数字,这是正则表达式决定的
传递给视图的所有参数都是字符串类型。而不像path()方法中可以指定转换成某种类型。在视图中接收参数时一定要小心。
要从URL捕获值,请使用尖括号。
捕获的值可以选择包括转换器类型。例如,用于 <int:name>捕获整数参数。如果未包含转换器/,则匹配除字符之外的任何字符串。
没有必要添加前导斜杠,因为每个URL都有。例如,它articles不是/articles。

传递额外的参数

URLconfs有一个钩子,允许您将额外的参数作为Python字典传递给视图函数。

该path()函数可以采用可选的第三个参数,该参数应该是传递给视图函数的额外关键字参数的字典。

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

在这个例子中,对于请求/blog/2005/,Django将调用 。views.year_archive(request, year=2005, foo='bar')

在联合框架中使用此技术 将元数据和选项传递给视图。

** 处理冲突 可以使用URL模式捕获命名关键字参数,并在其额外参数字典中传递具有相同名称的参数。发生这种情况时,将使用字典中的参数而不是URL中捕获的参数。**

将额外选项传递给include()

# main.py
from django.urls import include, pathurlpatterns = [path('blog/', include('inner'), {'blog_id': 3}),
]# inner.py
from django.urls import path
from mysite import viewsurlpatterns = [path('archive/', views.archive),path('about/', views.about),
]
#第二种方式
# main.py
from django.urls import include, path
from mysite import viewsurlpatterns = [path('blog/', include('inner')),
]# inner.py
from django.urls import pathurlpatterns = [path('archive/', views.archive, {'blog_id': 3}),path('about/', views.about, {'blog_id': 3}),
]

请注意,无论行的视图是否实际接受这些选项为有效,额外选项将始终传递到包含的URLconf中的每一行。因此,只有在您确定所包含的URLconf中的每个视图都接受您传递的额外选项时,此技术才有用。

URL的反向解析

Django提供了用于执行URL反转的工具,这些工具匹配需要URL的不同层: 在模板中:使用url模板标记。 在Python代码中:使用该reverse()函数。 在与处理Django模型实例的URL相关的更高级代码中:该get_absolute_url()方法。

from django.urls import pathfrom . import viewsurlpatterns = [#...path('articles/<int:year>/', views.year_archive, name='news-year-archive'),#...
]

根据这种设计,对应于年度归档文件的URL NNNN 是/articles/<nnnn>/。 您可以使用以下方法在模板代码中获取这些:

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
{# Or with the year in a template context variable: #}
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>

或者在Python代码中:

from django.http import HttpResponseRedirect
from django.urls import reversedef redirect_to_year(request):# ...year = 2006# ...return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))

url命名空间

URL命名空间可以保证反查到唯一的URL,即使不同的app使用相同的URL名称。

第三方应用始终使用带命名空间的URL是一个很好的做法。

类似地,它还允许你在一个应用有多个实例部署的情况下反查URL。 换句话讲,因为一个应用的多个实例共享相同的命名URL,命名空间提供了一种区分这些命名URL 的方法。

实现命名空间的做法很简单,在urlconf文件中添加app_name = 'polls'和namespace='author-polls'这种类似的定义。

#urls.py
from django.urls import include, pathurlpatterns = [path('author-polls/', include('polls.urls', namespace='author-polls')),path('publisher-polls/', include('polls.urls', namespace='publisher-polls')),
]
#polls/urls.py
from django.urls import pathfrom . import viewsapp_name = 'polls'
urlpatterns = [path('', views.IndexView.as_view(), name='index'),path('<int:pk>/', views.DetailView.as_view(), name='detail'),...
]

如果当前的app实例是其中的一个,例如我们正在渲染实例'author-polls'中的detail视图,'polls:index'将解析到'author-polls'实例的index视图。

根据以上设置,可以使用下面的查询: #python代码中

reverse('polls:index', current_app=self.request.resolver_match.namespace)

#模板视图中

{% url 'polls:index' %}

如果没有当前app实例,例如如果我们在站点的其它地方渲染一个页面,'polls:index'将解析到polls注册的最后一个app实例空间。 因为没有默认的实例(命名空间为'polls'的实例),将使用注册的polls 的最后一个实例。 这将是'publisher-polls',因为它是在urlpatterns中最后一个声明的。

URL命名空间和include的URLconf

可以通过两种方式指定include的URLconf的应用名称空间。

第一种

在include的URLconf模块中设置与urlpatterns属性相同级别的app_name属性。必须将实际模块或模块的字符串引用传递到include(),而不是urlpatterns本身的列表。

# polls/urls.py
from django.conf.urls import urlfrom . import viewsapp_name = 'polls'
urlpatterns = [url(r'^$', views.IndexView.as_view(), name='index'),url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),...
]
#urls.py
from django.conf.urls import include, urlurlpatterns = [url(r'^polls/', include('polls.urls')),
]

第二种

"""education URL ConfigurationThe `urlpatterns` list routes URLs to views. For more information please see:https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views1. Add an import:  from my_app import views2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views1. Add an import:  from other_app.views import Home2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf1. Import the include() function: from django.urls import include, path2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
import xadmin
from django.conf.urls import  url,re_path,include
from django.views.generic import TemplateView
from django.views.static import serve
from users.views import LoginView, RegisterView, LogoutView, AciveUserView, ForgetPwdView, ResetView, ModifyPwdView
from users.views import IndexView
from .settings import MEDIA_ROOT
urlpatterns = [# re_path('^$', TemplateView.as_view(template_name="index.html"),name='index'),re_path('^$', IndexView.as_view(), name='index'),re_path('^admin/', xadmin.site.urls),re_path('^login/$',LoginView.as_view(),name='login'),re_path('^register/$',RegisterView.as_view(),name='register'),re_path('^captcha/', include('captcha.urls')),re_path(r'^active/(?P<active_code>.*)/$', AciveUserView.as_view(), name="user_active"),re_path('^register/$', RegisterView.as_view(), name="register"),re_path('^logout/$', LogoutView.as_view(), name="logout"),re_path(r'^forget/$', ForgetPwdView.as_view(), name="forget_pwd"),re_path(r'^reset/(?P<active_code>.*)/$', ResetView.as_view(), name="reset_pwd"),re_path(r'^modify_pwd/$', ModifyPwdView.as_view(), name="modify_pwd"),# 用户相关url配置url(r'^users/', include(('users.urls','users'), namespace="users")),# 课程机构url配置re_path('^org/', include(('organization.urls','organization'), namespace="org")),# 课程相关url配置re_path('^course/', include(('course.urls','courses'), namespace="course")),# 配置上传文件的访问处理函数re_path('^media/(?P<path>.*)$', serve, {"document_root": MEDIA_ROOT}),# url(r'^static/(?P<path>.*)$',  serve, {"document_root":STATIC_ROOT}),# 富文本相关urlre_path('^ueditor/', include('DjangoUeditor.urls')),]#全局404页面配置
handler404 = 'users.views.page_not_found'
handler500 = 'users.views.page_error'

redirect()

redirect(to, permanent=False, args, *kwargs)[source]

根据传递进来的url参数,返回HttpResponseRedirect。

参数to可以是:

一个模型:将调用模型的get_absolute_url()函数,反向解析出目的url; 视图名称:可能带有参数:reverse()将用于反向解析url; 一个绝对的或相对的URL:将原封不动的作为重定向的目标位置。 默认情况下是临时重定向,如果设置permanent=True将永久重定向。

  • .传递视图名,使用reverse()方法反向解析url:
def my_view(request):...return redirect('some-view-name', foo='bar')
  • 重定向到硬编码的URL:
def my_view(request):...return redirect('/some/url/')
  • 重定向到一个完整的URL:
def my_view(request):...return redirect('https://example.com/')
  • 重定向反转
def update_time(request):  #进行要处理的逻辑  return redirect(reverse('test.views.invoice_return_index', args=[]))  #跳转到index界面

HttpResponse对象

  • 传递一个字符串 最简单的方式是传递一个字符串作为页面的内容到HttpResponse构造函数,并返回给用户:
from django.http import HttpResponse
response = HttpResponse("Here's the text of the Web page.")
response = HttpResponse("Text only, please.", content_type="text/plain")
# 可以将response看做一个类文件对象,使用wirte()方法不断地往里面增加内容。
response = HttpResponse()
response.write("<p>Here's the text of the Web page.</p>")
response.write("<p>Here's another paragraph.</p>")
  • 设置头部字段
response = HttpResponse()
response['Age'] = 120
del response['Age']

注意!与字典不同的是,如果要删除的头部字段如果不存在,del不会抛出KeyError异常。

HTTP的头部字段中不能包含换行。所以如果我们提供的头部字段值包含换行符(CR或者LF),将会抛出BadHeaderError异常。

  • 告诉浏览器将响应视为文件附件 让浏览器以文件附件的形式处理响应, 需要声明content_type类型和设置Content-Disposition头信息。 例如,给浏览器返回一个微软电子表格:
response = HttpResponse(my_data, content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="foo.xls"'

###文件上传 Django在处理文件上传时,文件数据被打包封装在request.FILES中。

  • 简单上传 首先,写一个form模型,它必须包含一个FileField:
# forms.py
from django import forms
class UploadFileForm(forms.Form):title = forms.CharField(max_length=50)file = forms.FileField()

处理这个表单的视图将在request.FILES中收到文件数据,可以用request.FILES['file']来获取上传文件的具体数据,其中的键值‘file’是根据file = forms.FileField()的变量名来的。 注意:request.FILES只有在请求方法为POST,并且提交请求的<form>具有enctype="multipart/form-data"属性时才有效。 否则,request.FILES将为空。

# views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
# 另外写一个处理上传过来的文件的方法,并在这里导入
from somewhere import handle_uploaded_file
def upload_file(request):if request.method == 'POST':form = UploadFileForm(request.POST, request.FILES) # 注意获取数据的方式if form.is_valid():handle_uploaded_file(request.FILES['file'])return HttpResponseRedirect('/success/url/')else:form = UploadFileForm()return render(request, 'upload.html', {'form': form})

请注意,必须将request.FILES传递到form的构造函数中

form = UploadFileForm(request.POST, request.FILES)

下面是一个处理上传文件的方法的参考例子: 遍历UploadedFile.chunks(),而不是直接使用read()方法,能确保大文件不会占用系统过多的内存。

def handle_uploaded_file(f):with open('some/file/name.txt', 'wb+') as destination:for chunk in f.chunks():destination.write(chunk)

python读GB级大文件

在python中读取文件一般来说有三种“读”的方法:.read()、.readline() 和 .readlines()。对于小文件,调用read()会一次性读取文件的全部内容,调用readline()每次读取一行内容,或者调用readlines()一次读取所有内容并按行返回list,都可以非常方便的实现,然而如果一次性读取GB级的文件,内存很容易就爆了。

  • 首推with open( ) 其实之前有很长一段时间不知道with open()的神奇作用,直到这次遇到问题,才发现它的奇妙之处。原来python中用with语句打开和关闭文件,包括了抛出一个内部块异常,并且,for line in f其实是将文件对象f视为一个迭代器,自动的采用缓冲IO和内存管理,所以不必担心大文件。让系统来处理,其实是最简单的方式,交给解释器,就万事大吉了。
#If the file is line based
with open('...') as f:for line in f:process(line) #
  • Read In Chunks
file = open("sample.txt")
while 1:
lines = file.readlines(100000)
if not lines:break
for line in lines:pass # do something
#or
def read_in_chunks(filePath, chunk_size=1024*1024):"""Lazy function (generator) to read a file piece by piece.Default chunk size: 1MYou can set your own chunk size """file_object = open(filePath)while True:chunk_data = file_object.read(chunk_size)if not chunk_data:breakyield chunk_data
if __name__ == "__main__":filePath = './path/filename'for chunk in read_in_chunks(filePath):process(chunk) #
  • 带缓存的文件读取
# File: readline-example-3.py
file = open("sample.txt")
while 1:lines = file.readlines(100000)if not lines:breakfor line in lines:pass # do something

同时上传多个文件

如果要使用一个表单字段同时上传多个文件,需要设置字段HTML标签的multiple属性为True,如下所示:

# forms.pyfrom django import formsclass FileFieldForm(forms.Form):file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
# views.py
from django.views.generic.base import View
from .forms import FileFieldFormclass FileFieldView(View):form_class = FileFieldFormtemplate_name = 'upload.html'  # 用你的模版名替换.success_url = '...'  # 用你的URL或者reverse()替换.def post(self, request, *args, **kwargs):form_class = self.get_form_class()form = self.get_form(form_class)files = request.FILES.getlist('file_field')if form.is_valid():for f in files:...  # Do something with each file.return self.form_valid(form)else:return self.form_invalid(form)

上传文件处理器

当用户上传一个文件的时候,Django会把文件数据传递给上传文件处理器–一个类。

上传处理器的配置定义在FILE_UPLOAD_HANDLERS中,默认为:

["django.core.files.uploadhandler.MemoryFileUploadHandler", "django.core.files.uploadhandler.TemporaryFileUploadHandler"]

MemoryFileUploadHandler和TemporaryFileUploadHandler定义了Django的默认文件上传行为:将小文件读取到内存中,大文件放置在磁盘中。

在你保存上传文件之前,数据需要储存在某个地方。通常,如果上传文件小于2.5MB,Django会把整个内容存到内存。 这意味着,文件的保存仅仅涉及到内存中的读取和磁盘的写入,所以非常快。但是,如果上传的文件很大,Django会把它写入一个临时文件,储存在你的系统临时目录中。在类Unix的平台下,Django会生成一个文件,名称类似于/tmp/tmpzfp6I6.upload。

动态生成CSV文件

  • 使用Python的CSV库

Python自带处理CSV文件的标准库csv。csv模块的CSV文件创建功能作用于类似于文件对象创建,并且Django的HttpResponse对象也是类似于文件的对象。

import csv
from django.http import HttpResponsedef some_view(request):# Create the HttpResponse object with the appropriate CSV header.response = HttpResponse(content_type='text/csv')response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'writer = csv.writer(response)writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])return response

响应对象的MIME类型设置为text/csv,告诉浏览器,返回的是一个CSV文件而不是HTML文件。

响应对象设置了附加的Content-Disposition协议头,含有CSV文件的名称。文件名随便取,浏览器会在“另存为...”对话框等环境中使用它。

要在生成CSV的API中使用钩子非常简单:只需要把response作为第一个参数传递给csv.writer。csv.writer方法接受一个类似于文件的对象,而HttpResponse对象正好就是这么个东西。

对于CSV文件的每一行,调用writer.writerow,向它传递一个可迭代的对象比如列表或者元组。

CSV模板会为你处理各种引用,不用担心没有转义字符串中的引号或者逗号。只需要向writerow()传递你的原始字符串,它就会执行正确的操作。

在下面的例子中,利用Python的生成器来有效处理大尺寸CSV文件的拼接和传输:

import csvfrom django.http import StreamingHttpResponseclass Echo(object):"""An object that implements just the write method of the file-likeinterface."""def write(self, value):"""Write the value by returning it, instead of storing in a buffer."""return valuedef some_streaming_csv_view(request):"""A view that streams a large CSV file."""# Generate a sequence of rows. The range is based on the maximum number of# rows that can be handled by a single sheet in most spreadsheet# applications.rows = (["Row {}".format(idx), str(idx)] for idx in range(65536))pseudo_buffer = Echo()writer = csv.writer(pseudo_buffer)response = StreamingHttpResponse((writer.writerow(row) for row in rows),content_type="text/csv")response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'return response

转载于:https://my.oschina.net/jiansin/blog/1842718

Django视图层总结相关推荐

  1. Django - - - -视图层之视图函数(views)

    阅读目录(Content) 视图层之视图函数(views) 一个简单的视图 1.HttpRequest 2.HttpResponse 1.render 函数 2.redirect 函数 对比rende ...

  2. Django的视图层简介

    Django的视图层 视图函数 所谓视图函数,其实就是我们Django项目中各个应用中的views.py文件中定义的每个用来处理URL路由映射到这里的逻辑函数.一个视图函数简称视图,它是个简单的Pyt ...

  3. django ajax 更新表格_Django(反向解析,路由分发、名称空间、视图层、虚拟环境、Django版本、json,CBV)...

    https://www.zhihu.com/video/1249117508688711680 每日测验 """ 今日考题 1.列举你知道的orm数据的增删改查方法 2. ...

  4. django redirect传递参数_Django 视图层(四):视图函数 - views.py

    介绍 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图 ...

  5. 关于Django路由层简单笔记

    Django-路由层 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来的某个U ...

  6. django模板层 (标签,过滤器,自定义inclusion_tag,模板的继承与导入)

    后端朝前端页面传递数据的方式:return HttpResponse(''字符串类型) 具体参照上一篇博客的视图层此处主要介绍通过 render方式传值:第一种: return render(requ ...

  7. 视图层详解,cbv和fbv,文件上传

    day64 一.复习 二.视图层之请求对象 三.视图层之响应对象 补充知识之json序列化与反序列化 四.cbv和fbv 五.文件上传 六.postman软件 七.form表单,提交地址 八.Pych ...

  8. 05 django路由层

    路由 顾名思义,就是指路牌,请求过来根据指路牌的指示指向不同的视图函数. 路由层主要掌握: re_path正则匹配路径: 满足条件的都走同一个视图函数,多用在请求数据,比如图书馆,那一个书架哪一本书, ...

  9. python代码函数字符查询宝典书籍_Django基础五之django模型层(一)单表操作

    二 单表操作 一.创建表 创建模型 创建名为book的app,在book下的models.py中创建模型: from django.db importmodels#Create your models ...

最新文章

  1. 【错误记录】编译 ijkplayer 报错 (fatal error: libyuv.h: No such file or directory #include “libyuv.h“ )
  2. Mac OS X 10.8.5 安装编译glib
  3. UGUI实现接口事件
  4. 聚类结果不好怎么办_使用bert-serving生成词向量并聚类可视化
  5. libzdb 连接到mysql_MySQL 连接
  6. 支持商用吗_可商用的插画素材 | 美翻了
  7. 2021中国民营企业500强调研分析报告
  8. 斗鱼服务器维护不能改名,斗鱼tv怎么改名字-斗鱼tv修改昵称的方法 - 河东软件园...
  9. 隐式人体表示生成虚拟视点+构建关节点的3D神经模型
  10. NTSC、PAL、SECAM三大制式简介
  11. PREEMPT_RT 高精度定时器
  12. Ubuntu16.04分辨率过低,无法调高
  13. photoshop批处理改变图片大小
  14. POJ 2210 Metric Time G++
  15. Python网络爬虫与信息提取(17)—— 题库爬取与整理+下载答案
  16. 机器学习中的启发式算法(heuristic algorithm)
  17. Win11系统开机黑屏无法显示桌面怎么解决?
  18. 计算机科学数学科目,计算机科学与技术考研考哪些科目 备考技巧有哪些
  19. 51单片机 AD转换
  20. 你是如何坚持读完《算法导论》这本书的?

热门文章

  1. Java学习笔记24
  2. iOS架构-分离静态库.a文件并导出.m伪代码文件(11)
  3. SharpUpdater:开源的.NET桌面程序自动更新组件
  4. 第八章 Health Check
  5. Appium如何获取appPackage和appActivity
  6. session cookie
  7. 触发transition的几种方式--转
  8. 使用xshell5 从CentOS主机download资料
  9. rhel 6.4 + udev + 11.2.0.3 + asm 单点安装
  10. 【 js 片段 】如何组织表单的默认提交?【亲测有效】