Django框架
Django创建视图函数
在Django中定义视图函数时,要注意两点:
•(1)视图函数的参数中必须要传request
参数
•(2)返回值必须要写在HttpResponseBase
或其子类
中
在urls.py中定义视图函数如下:
from django.contrib import admin
from django.http import HttpResponse
from django.urls import path
def index(request): # 必须填加参数request
return HttpResponse('Hello World')
urlpatterns = [
path('admin/', admin.site.urls),
path('', index) # 第一个参数为路由 第二个参数为视图函数名称(不需要加括号)
]
访问http://127.0.0.1:8000/ 网页显示:
再次在urls.py中定义视图函数测试如下:
from django.contrib import admin
from django.http import HttpResponse
from django.urls import path
def news(request): # 必须填加参数request
return HttpResponse('新闻首页')
def book(request):
return HttpResponse('图书首页')
urlpatterns = [
path('admin/', admin.site.urls),
path('', news), # 第一个参数为路由 第二个参数为视图函数名称(不需要加括号)
path('book/', book)
]
网页显示:
在实际项目中,建立视图函数不是在urls.py中,而是在不同的app中实现的
•执行python manage.py startapp news
新建名为news的app,news/views.py如下:
from django.shortcuts import render
from django.http import HttpResponse
def news(request):
return HttpResponse('新闻首页')
•book/views.py如下:
from django.shortcuts import render
from django.http import HttpResponse
def book(request):
return HttpResponse('图书首页')
•项目下的urls.py如下:
from django.contrib import admin
from django.http import HttpResponse
from django.urls import path
from book.views import book
from news.views import news
def index(request):
return HttpResponse('首页')
urlpatterns = [
path('admin/', admin.site.urls),
path('', index),
path('book/', book),
path('news/', news),
]
网页显示:
Django的DEBUG模式
•Django框架会默认开启Debug模式,在settings.py中如下:
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True #默认开启DEBUG模式
•开启了debug模式后,修改代码后并按下Ctrl+S
或者离开PyCharm窗口,Django会自动重启项目,不需要重启项目
•在执行项目的过程中遇到异常时,会将错误信息显示到页面和控制台中,因此项目上线时,必须要关闭Debug模式,否则会暴露项目信息、存在很大的安全隐患
关闭DEBUG模式
需要在setting文件中进行配置,设置如下:
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False #关闭debug模式
ALLOWED_HOSTS = ['127.0.0.1']
•即需要要将Debug模式
设为False,还要设置ALLOWED_HOSTS
进行更改,在开发时一般设为本地(127.0.0.1)
Django的视图与URL
视图(Views)
•视图一般都定义在各个app的views.py
中,并且视图的第一个参数必须是request(一个HttpRequest对象,准确来说是一个django.core.handlers.wsgi.WSGIRequest对象),同时返回结果必须是HttpResponseBase对象或者子类的对象
•HttpRequest对象
存储了请求过来的所有信息,包括携带的各种参数和一些头部信息等
•视图文件(views.py)
一般用于完成一些业务逻辑,比如请求时添加一本书籍,那么可以通过request来接收这些数据,然后存储到数据库中,最后再把执行的结果返回给浏览器,呈现给我们
•业务逻辑book/views.py
如下:
from django.http import HttpResponse
def book(request): # 定义视图函数
return HttpResponse("图书首页")
•通过urls.py文件来调用视图函数,urls.py
如下:
from book import views
urlpatterns = [
path("book/",views.book) # views.book为调用视图函数book 不需要加括号
]
URL映射
•视图函数在views.py中定义好后,要与URL进行映射,从而保证用户在浏览器中输入指定URL可以请求到指定的视图函数
•在输入了某个URL、请求网站时,django会从项目文件夹中的urls.py文件中寻找对应的视图函数进行映射
•settings.py
配置如下:
ROOT_URLCONF = 'django_one.urls'
•在urls.py文件中有一个urlpatterns变量(列表),Django会从每个变量的路径匹配到对应视图函数
•匹配规则需要使用django.urls.path
或django.urls.url
函数进行包裹,这个函数会根据传入的参数返回URLPattern
或者是URLResolver
的对象,示意如下:
urlpatterns = [
path('admin/', admin.site.urls),
path('', index), # url为:127.0.0.1 视图函数为index
path('book/', book), #url为127.0.0.1/book/ 视图函数为book
path('news/', news),
]
URL中添加参数
有时候url中需要添加一些参数来代表特定的意义:
•csdn首页的URL:https://www.csdn.net/
•个人博客的URL:https://blog.csdn.net/qq_45261963/article/details/114323642中114323642
代表博客id
•qq音乐中周杰伦的歌URL:https://y.qq.com/portal/search.html#page=1&searchid=1&remoteplace=txt.yqq.top&t=song&w=%E5%91%A8%E6%9D%B0%E4%BC%A6中包含很多参数,其中page
为页码数
•由上面可以看出,url中要动态传入参数时,有两种不同形式
•在Django中要实现传入参数,也有两种方式:
•(1) 路径传参:
•形式为url/<参数名>
,类似于/article/details/114323642
这几个参数,需要在path函数中使用尖括号的形式来定义一个参数,例如book/<book_id>/
,这与Flask中URL的传参类似
•通过命令行django-admin startproject django_url
新建一个Django项目名为django_url,再进入项目django_url文件夹,运行python manage.py startapp book
创建名为book的app,book/views.py
如下:
from django.http import HttpResponse
def book(request):
return HttpResponse('图书首页')
def book_details(request, book_id):
return HttpResponse('图书id:{}'.format(book_id))
•项目文件夹中urls.py 如下:
from django.contrib import admin
from django.urls import path
from book import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.book),
path('book/<book_id>', views.book_details) # 需要传入参数<book_id>
]
•使用pycharm运行,网页显示:
•显然使用上面这一种方法可以传入参数,并且可以为访问
注意
•视图函数中的参数名称必须与urls.py
中尖括号中的参数名称保持一致,否则会出错
•视图函数中还可以传入多个参数,views.py如下:
from django.http import HttpResponse
def book(request):
return HttpResponse('图书首页')
def book_details(request, book_id, cate_id):
return HttpResponse('图书 id:{} 分类 id:{}'.format(book_id, cate_id))
•项目文件夹中urls.py 如下:
from django.contrib import admin
from django.urls import path
from book import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.book),
path('book/<book_id>/<cate_id>', views.book_details)
]
•网页显示为:
注意
•视图函数中的参数名称和个数都需要与urls中的保持一致
•(2)关键字传参:
•形式为url?参数=值
,类似于all?keyword=PYTHON&from_source=nav_suggest
,这种方式直接使用get()方法获取参数即可,即使用request.GET.get(参数名称)
的方式获取参数值
•视图函数的views.py如下:
from django.http import HttpResponse
def book(request):
return HttpResponse('图书首页')
def book_details(request, book_id, cate_id):
return HttpResponse('图书 id:{} 分类 id:{}'.format(book_id, cate_id))
def book_list(request):
book_id = request.GET.get('id')
return HttpResponse('图书 id:{}'.format(book_id))
•项目文件夹urls.py如下:
from django.contrib import admin
from django.urls import path
from book import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.book),
path('book/<book_id>/<cate_id>', views.book_details),
path('book_list/', views.book_list)
]
•网页显示为:
•也可以传入多个参数,views.py如下:
from django.http import HttpResponse
def book(request):
return HttpResponse('图书首页')
def book_details(request, book_id, cate_id):
return HttpResponse('图书 id:{} 分类 id:{}'.format(book_id, cate_id))
def book_list(request):
book_id = request.GET.get('id')
return HttpResponse('图书 id:{}'.format(book_id))
def book_lists(request):
book_id = request.GET.get('id')
cate_id = request.GET.get('cid')
return HttpResponse('图书id:%s,分类id:%s' % (book_id, cate_id)) # 传入多个参数
•项目文件夹urls.py如下:
from django.contrib import admin
from django.urls import path
from book import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.book),
path('book/<book_id>/<cate_id>', views.book_details),
path('book_list/', views.book_list),
path('book_lists/', views.book_lists)
]
•网页显示为:
模块化和内置转换器
URL模块化
•在Flask框架中有蓝图,URL模块化与蓝图是类似的概念
•在一个完整项目中,一般不可能只有一个app,而是有多个app,如果把所有app的views中的视图函数都放在urls.py中进行映射,肯定会让代码显得冗长混乱
•Django框架提供了一个机制,即为URL模块化,可以在各自app内部中包含自己的URL匹配规则,而在项目的urls.py中再统一包含各个app的URLS,这就需要用到include函数
进行配置即可
•举例如下:
•通过python manage.py startapp news
命令再创建一个app名为news,news/views.py
如下:
from django.http import HttpResponse
def news(request):
return HttpResponse('新闻首页')
•项目文件夹下的urls.py
from django.contrib import admin
from django.urls import path
from book import views as bviews # book的视图
from news import views as nviews # news的视图
urlpatterns = [
path('admin/', admin.site.urls),
path('book/', bviews.book),
path('book/<book_id>/<cate_id>', bviews.book_detail),
path('book_list/', bviews.book_list),
path('news/', nviews.news),
]
•可以看到,为了避免从book导入的views与从news导入的views重名而产生冲突,必须重命名
•而且,当各个app中的视图函数增多后,在urlpatterns列表中的path中的urls自然也会同步增多,显得很重复混乱并且不美观
•因此可以选择在各自的app中分别定义自己内部的路由,然后在项目文件夹的urls.py
中将这些路由包含进去即可
•在book app下新建urls.py如下:
from django.urls import path
from . import views
urlpatterns = [
path('', views.book),
path('book_detail/<book_id>/<cate_id>', views.book_detail),
path('book_list/', views.book_list),
]
•在news app下新建urls.py如下:
from django.urls import path
from . import views
urlpatterns = [
path('', views.news),
]
•django_url/urls.py如下:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('book/', include('book.urls')),
path('news/', include('news.urls')),
]
•网页测试如下:
•显然,与不使用URL模块化访问是一样的
•可以看到,此时访问每个视图函数,必须加上在django_url/urls.py
中path方法中传入的第一个参数,如访问book下的app就必须在url中加入book前缀
•include方法的作用是拼接django_url/urls.py
中path方法的第一个参数与每个app中urls.py中定义的路由,以形成完整的路由进行访问
注意
•include方法里的参数为app中的urls.py文件的具体路径(一般直接为 app名称.urls)
内置转换器
内置转换器一般用于限制参数类型
,如id必须为整数等,django中有5种内置转换器:
•int 整型
•path 路径
•slug 限制字母数字和下划线
•str 字符串
•uuid
它们都是通过正则表达式
实现的
•uuid是128位的全局唯一标识符(univeral unique identifier),通常用32位的一个字符串的形式来表现,具体介绍和使用可以参考
https://www.cnblogs.com/franknihao/p/7307224.html
例如:path(‘book_detail/<int: book_id>/<cate_id>’, views.book_detail)
,即限制参数book_id必须为整型,测试如下:
•此时cate_id
可以为其他任意类型,而book_id
必须为整型