Django框架之URL与视图详解(你想要的这都有!!!)

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/ 网页显示:
Django框架之URL与视图详解(你想要的这都有!!!)
       再次在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)
]

网页显示:
Django框架之URL与视图详解(你想要的这都有!!!)
在实际项目中,建立视图函数不是在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框架之URL与视图详解(你想要的这都有!!!)

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.pathdjango.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/114323642114323642代表博客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运行,网页显示:
Django框架之URL与视图详解(你想要的这都有!!!)

       •显然使用上面这一种方法可以传入参数,并且可以为访问

注意

       •视图函数中的参数名称必须与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)
]

       •网页显示为:
Django框架之URL与视图详解(你想要的这都有!!!)

注意

       •视图函数中的参数名称和个数都需要与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)
]

       •网页显示为:
Django框架之URL与视图详解(你想要的这都有!!!)
       •也可以传入多个参数,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)
]

       •网页显示为:
Django框架之URL与视图详解(你想要的这都有!!!)

模块化和内置转换器

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

       •网页测试如下:

Django框架之URL与视图详解(你想要的这都有!!!)

       •显然,与不使用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必须为整型,测试如下:
Django框架之URL与视图详解(你想要的这都有!!!)

       •此时cate_id可以为其他任意类型,而book_id必须为整型

上一篇:2021-02-26 企业vue router 示例


下一篇:Node Express框架快速入门教程