视图
视图可以在项目的urls.py中编写,但一般都写在app的views.py中。
需要注意的是:
- 视图的第一个参数永远都是request(一个HttpRequest)对象。
- 这个对象存储了请求过来的所有信息,包括携带的参数以及一些头部信息等。
- 这个对象存储了请求过来的所有信息,包括携带的参数以及一些头部信息等。
- 视图函数的返回结果,必须是HttpResponseBase对象或者子类的对象。
定义视图
- 在项目的urls.py中编写: ```python from django.contrib import admin from django.urls import path, include from django.http import HttpResponse from movie import views # 导入创建的app
“”” 1、必须传参request 2、返回值必须为HttpResponse “””
定义视图
def index(request): return HttpResponse(“Hello World”)
def movie(request): return HttpResponse(“电影页面”)
URL映射
urlpatterns = [ path(‘admin/‘, admin.site.urls), path(‘’, index), path(‘movie/‘, movie),
# path('movie/', views.movie)
]
- 在app的views.py中编写:```pythonfrom django.http import HttpResponsedef movie(request):# raise ValueErrorreturn HttpResponse("电影页面")
URL映射
视图定义完后,要与URL进行映射。即用户在访问某个URL,请求到网站时,django会从项目的urls.py文件中寻找对应的视图。
在urls.py文件中有一个 urlpatterns 变量,django会从这个变量中读取所有的匹配规则。匹配规则需要使用 django.urls.path 函数进行包裹,其会根据传入的参数返回 URLPattern 或者是 URLResolver 的对象。
# URL映射urlpatterns = [path('admin/', admin.site.urls),path('', index),path('movie/', movie),# path('movie/', views.movie)]
urls官网手册:https://docs.djangoproject.com/en/3.0/ref/urls/
URL中添加参数
有时候,url中包含了一些参数需要动态调整。一般有两种传参方式:直接传参和关键字传参。
比如,想要获取电影的第几页,传参方式如下:
直接传参:http://127.0.0.1:8000/movie_list/3/2
关键字传参:http://127.0.0.1:8000/movie_type/?name=爱情片
定义视图:
from django.http import HttpResponse# Create your views here.def movie(request):# raise ValueErrorreturn HttpResponse("电影页面")'''直接传参'''def movie_list(request, mid, uid):# raise ValueErrorreturn HttpResponse("电影第 %s 页, 动作片第 %s 页" % (mid, uid))'''关键字传参'''def movie_type(request):# request.GET其中GET会返回一个字典type_name = request.GET.get('name')return HttpResponse("电影类型是 %s" % type_name)
URL映射:
# URL访问格式:http://127.0.0.1:8000/movie/3/1urlpatterns = [path('admin/', admin.site.urls),path('', index),path('movie/', mviews.movie),# 直接传参path('movie_list/<mid>/<uid>', mviews.movie_list),# 关键字传参path('movie_type/', mviews.movie_type)]
URL模块化
在Django项目中,不可能只有一个app,如果把所有的app的views中的视图,都放在urls.py中进行映射,肯定会让代码显得非常乱。
因此,django提供了一个方法,可以在app内部包含自己的url匹配规则,然后在项目的urls.py中再统一包含这个app的urls,若要实现该方式,需要导入 include 函数。
定义app视图:
from django.http import HttpResponse# Create your views here.def book(request):# raise ValueErrorreturn HttpResponse("图书页面")def book_detail(request):# raise ValueErrorres = request.GET.get('id')return HttpResponse("图书第 %s 页" % res)
创建app的urls.py文件:
from django.urls import pathfrom . import viewsurlpatterns = [path('', views.book), # 表示book/# http://127.0.0.1:8000/book/detail/?id=2path('detail/', views.book_detail) # 表示book/detail/]
在urls.py文件中,把所有和book这个app相关的url都移动到app/urls.py中。
项目的urls文件:
from django.contrib import adminfrom django.urls import path, include # 导入includeurlpatterns = [path('admin/', admin.site.urls),# URL模块化path('book/',include("book.urls"))]
通过include函数包含book.urls,以后再请求book相关的url时,都需要加一个book的前缀。
include其他用法
可以直接指定应用命名空间,以代替定义app_name。
include(module, namespace=None)include(pattern_list)include((pattern_list, app_namespace), namespace=None)
Django内置转换器
通过正则表达式来进行规则匹配,内置转换器包含int、str、uuid和path。
from django.urls import converters
UUID的使用:https://www.cnblogs.com/franknihao/p/7307224.html
内置转换器的使用:
urlpatterns = [path('admin/', admin.site.urls),path('', index),path('movie/', mviews.movie),# 限制传入参数的类型path('movie_list/<int:mid>/<str:uid>', mviews.movie_list)
URL命名与反转
- 1.为什么需要URL命名?
因为在项目开发的过程中,URL地址可能经常变动,如果写死会经常去修改。给url取个名字,以后进行反转时,使用url的名字即可,无需关心URL是什么。 - 2.如何给一个URL指定名称?
path("",views.index,name="index") - 3.应用命名空间
在多个app之间可能产生同名的URL,为了避免这种情况,可以使用命名空间来加以区分。需在app的urls.py中添加app_name。
新建两个app:
$ python manage.py startapp cms$ python manage.py startapp front'''项目的urls.py文件'''urlpatterns = [path('admin/', admin.site.urls),path('', include("front.urls")),path('cms/', include("cms.urls")),]
URL命名与反转
'''views.py'''def index(request):name = request.GET.get('name')if name:return HttpResponse('前台页面首页,name是 %s' % name)else:"""重定向到login"""# return redirect('login/')# 反转,参数login对应urls中的name值return redirect(reverse('login'))'''url.py'''urlpatterns = [# 使用name给URL命名path('', views.index, name="index"),# path('login/', views.login, name="login"),# 若使用反转,url名称变动,不影响url映射path('signin/', views.login, name="login")]
应用命名空间
'''views.py'''def index(request):name = request.GET.get('name')if name:return HttpResponse('前台页面首页,name是 %s' % name)else:# 使用应用命名空间,指定跳转的app urlreturn redirect(reverse('front:login'))'''urls.py'''# 定义应用命名空间app_name = 'front'urlpatterns = [# 使用name给URL命名path('', views.index, name="index"),# path('login/', views.login, name="login"),# 若使用反转,url名称变动,不影响url映射path('signin/', views.login, name="login")]
实例命名空间
一个app可以创建多个实例,可以使用多个URL映射同一个App。在做反转时,如果使用应用命名空间,就会发生混淆,为了避免这个问题,可以使用实例命名空间。
使用 namespace 定义实例命名空间:
'''项目的urls.py文件'''from django.contrib import adminfrom django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('', include("front.urls")),path('cms/', include("cms.urls")),# 实例命名空间path('cms1/', include("cms.urls", namespace='cms1')),path('cms2/', include("cms.urls", namespace='cms2')),]'''app的views.py文件'''from django.shortcuts import redirect, reversefrom django.http import HttpResponse# Create your views here.def index(request):# 查看当前访问的实例命名空间current_namespace = request.resolver_match.namespaceprint(current_namespace)return HttpResponse('后台页面首页')
URL反转传递参数
如果这个url中需要传递参数,那么可以通过 kwargs 来传递参数。
reverse("book:detail",kwargs={"book_id":1})
因为django中的reverse反转url时,不区分GET请求和POST请求,因此不能在反转的时候,添加查询字符串的参数。如果想要添加查询字符串的参数,只能手动的添加。
login_url = reverse("front:singin") + "?name=jr"return redirect(login_url)
示例:
- app的views.py文件: ```python from django.shortcuts import render, redirect, reverse from django.http import HttpResponse
Create your views here.
def index(request): “””查看当前访问的实例命名空间””” current_namespace = request.resolver_match.namespace print(current_namespace)
# return HttpResponse('后台页面首页')"""url反转传参"""# 默认反转的URL:http://127.0.0.1:8000/cms/login/2/return redirect(reverse('cms:admin', kwargs={'lid': 2})) # 直接传参# return redirect(reverse('cms:login') + '?name=Rick') # 关键字传参
def admin(request, lid): return HttpResponse(‘后台管理页面, id是 %s’ % lid)
def login(request): name = request.GET.get(‘name’) return HttpResponse(‘后台登录页面, name是 %s’ % name)
2. app的urls文件:```pythonfrom django.urls import pathfrom . import views# 定义应用命名空间app_name = 'cms'urlpatterns = [path('', views.index, name="index"),path('login/', views.login, name='login'),path('admin/<lid>/', views.admin, name='admin')]
指定默认参数
"""views.py"""from django.http import HttpResponsedef admin(request, lid=1): # 默认参数return HttpResponse('后台管理页面, id是 %s' % lid)"""urls.py"""from django.urls import pathfrom . import viewsurlpatterns = [path('admin/', views.admin, name='admin'), # 接收默认参数path('admin/<lid>/', views.admin, name='admin') # 传递指定参数]
re_path正则匹配URL
使用re_path正则表达式可以实现一些复杂的URL规则匹配需求,re_path的参数和path参数一模一样,只不过第一个参数,也就是route可以为一个正则表达式。
"""views.py"""from django.http import HttpResponsedef birthday_year(request, year):return HttpResponse('您的生日年份是%s' % year)"""urls.py"""from django.urls import path, re_pathfrom . import views# re_path()和url()都能达到同样的正则匹配效果from django.conf.urls import urlurlpatterns = [# ?P<year>为传参固定格式re_path(r'byear/(?P<year>\d{4})$', views.birthday_year)]
