这一篇教程,我们一起来了解一些Django的URL Name和通用视图的内容。
一、URL Name
我们在做URL分发时,通过“path()”方法将一个路径匹配一个视图函数。
示例代码:
path('details<int:id>', shopviews.getgoodsdetails),
这样的路径,当我们访问类似“http://127.0.0.1:8888/details1”这样的网址时,就能够调用相应的视图进行处理。
不过,假如我们在完成了项目之后,想把这样的路径改为“http://127.0.0.1:8888/details/1”的格式,那就意味着所有使用了原有格式的路径都需要进行修改,这样的修改不能保证完全不会出现遗漏。
为了避免这种不安全的修改,我们在项目编写时,就可以主动去处理可能出现的问题。
在“path()”方法的参数中,可以再提供一个“name”参数的值,为“URL”设定一个名称。
然后,模板中使用“URL”时,不再写具体的路径,而是通过模板标记{% url 'URL名称' 更多参数%}
自动产生相应的路径。
例如一个商品列表页面,点击某一商品时,能够进入该商品的详情页。
1、定义模型类并创建数据库表
大家可以参考《Django2:Web项目开发入门笔记(8)》创建商品的模型类和数据库表。
2、定义视图函数
示例代码:
def getgoodslist(request): goodslist = GoodsInfo.objects.all() return render(request, 'goods_list.html', {'goodslist': goodslist}) def getgoodsdetails(request, id): goodsdetails = GoodsInfo.objects.filter(id=id) return render(request, 'goods_details.html', {'goodsdetails': goodsdetails})
3、配置URL分发
示例代码:
from MyShop import views as shopviews
path('', shopviews.getgoodslist), path('details<int:id>', shopviews.getgoodsdetails, <strong>name='details'</strong>),
4、创建模板
示例代码:(goods_list.html)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>商品列表</title> </head> <body> <h3>商品列表</h3> {% for goods in goodslist %} <p><a href="<strong>{%%20url%20'details'%20goods.id%20%}</strong>">{{ goods.id }}.{{ goods.goods_name }}</a></p> {% endfor %} </body> </html>
在上方代码中,模板标记“{% url ‘details’ goods.id %}”中的“‘details’”对应的就是URL分发配置中的URL“details<int:id>”
参数“goods.id”对应的就是“<int:id>”。
示例代码:(goods_details.html)
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>商品详情</title> </head> <body> {% for info in goodsdetails %} 名称:{{ info.goods_name }} 数量:{{ info.goods_number }} 价格:{{ info.goods_price }} {% endfor %} </body> </html>
完成上方代码中后,大家可以启动开发服务器,进行测试。
打开商品列表的页面后,点击商品名称就能够打开对应的商品详情页面。
此时,浏览器地址栏中的地址类似于“http://127.0.0.1:8888/details1”。
然后,大家可以把URL分发配置中的URL进行修改。
示例代码:
path('details/<int:id>', shopviews.getgoodsdetails, name='details'),
修改之后,刷新商品列表,并点击商品名称打开详情页面。
此时,浏览器地址栏中的地址类似于“http://127.0.0.1:8888/details/1”。
二、通用视图
1、TemplateView
按照我们之前所学内容,如果想让一个模板的内容呈现为页面,我们需要自定义一个视图函数。
哪怕只是一个没有数据加载的静态页面,也需要这么去做。
例如,我们有一个“hello.html”的模板。
示例代码:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>欢迎</title> </head> <body> 你好!欢迎访问小楼帅哥的个人网站! </body> </html>
这个模板内容与数据无关,呈现为页面之后,不会再有任何变化。
像这样的页面,实际上我们无需定义视图函数,可以直接使用Django给我们提供的通用模板视图类“TemplateView”。
在配置URL分发时,我们需要导入这个类,然后在“path()”方法中调用这个类的“as_view()”方法,并指定“as_view()”方法的“template_name”参数值为模板名称。
示例代码:
from django.views.generic.base import TemplateView
path('hello/', TemplateView.as_view(template_name='hello.html')),
这样结束之后,我们就可以启动开发服务器,访问“hello/”这个路径所打开的页面了。
2、ListView
“ListView”能够方便的帮助我们实现列表视图。
在‘views.py’文件中,我们不再定义视图函数,而是定义视图类继承“ListView”类。
示例代码:
from MyShop.models import GoodsInfo from django.views.generic.list import ListView class GoodsListView(ListView): model = GoodsInfo template_name = 'goods_list2.html'
在视图类中,我们只需要指定数据来源的模型类以及相应的模板文件。
然后,在URL分发配置中,我们添加新的配置。
示例代码:
path('list2/', shopviews.GoodsListView.as_view(),name='goods_list2'),
通过自定义视图类的“as_view()”方法,就能够将模型所有数据与模板进行整合。
最后,在视图中我们遍历数据对象,完成数据内容的填充。
示例代码:(goods_list2.html的关键代码)
<h3>商品列表</h3> {% for goods in <strong>object_list</strong> %} <p><a href="{%%20url%20'details'%20goods.id%20%}">{{ goods.id }}.{{ goods.goods_name }}</a></p> {% endfor %}
这里大家要注意,数据对象的名称为“object_list”,不再是自定义的名称。
上述操作是将全部商品数据在页面上呈现,如果我们只想呈现出符合某种条件的数据,该怎么做呢?
例如,我们只显示所有商品数据的前5条。
我们可以在自定义视图类中,重写“get_queryset()”方法。
示例代码:
<strong># views.py</strong> class GoodsList5View(ListView): template_name = 'goods_list3.html' def get_queryset(self): context = GoodsInfo.objects.all()[0:5] return context <strong>#urls.py</strong> path('list3/', shopviews.GoodsList5View.as_view(), name='goods_list3'), <strong>#goods_list3.html</strong> <h3>商品列表</h3> {% for goods in object_list %} <p><a href="{%%20url%20'details'%20goods.id%20%}">{{ goods.id }}.{{ goods.goods_name }}</a></p> {% endfor %}
3、DetailView
“DetailView”是通用详情视图。
我们可以通过继承“DetailView”类,完成商品详情的视图类。
然后,通过配置URL分发和创建相应的模板完成查看商品详情的功能。
示例代码:
<strong>#views.py</strong> class GoodsDetailView(DetailView): model = GoodsInfo template_name = 'goods_details2.html' <strong>#urls.py</strong> path('goods_details/<strong><pk></strong>', shopviews.GoodsDetailView.as_view(), name='goods_details'), <strong>#goods_details2.html</strong> <body> 名称:{{ object.goods_name }} 数量:{{ object.goods_number }} 价格:{{ object.goods_price }} 管理员:{{ manager }} </body>
注意上方代码中,URL分发配置中的URL参数要使用“<pk>”,也就是“Primary Key”(主键)的意思。
如果不是通过主键查询可以写成<slug:参数名称>。
在《Django2:Web项目开发入门笔记(4)》中曾经提到,slug类型是由字母、数字、横线以及下划线其中一种或多种组成的字符串。
我们除了能够查询到某个商品的详情,还可以在模型数据的基础上增加一些内容。
例如,把每个商品详情的末尾加上“管理员:小楼” 。
示例代码:
<strong>#views.py</strong> class GoodsDetailView(DetailView): model = GoodsInfo template_name = 'goods_details2.html' <strong> def get_context_data(self, **kwargs):</strong> <strong> context = super().get_context_data(**kwargs)</strong> <strong> context['manager'] = '小楼'</strong> <strong> return context</strong> <strong># goods_details2.html</strong> <body> 名称:{{ object.goods_name }} 数量:{{ object.goods_number }} 价格:{{ object.goods_price }} <strong>管理员:{{ manager }}</strong> </body>
以上代码中,红色部分为新增内容。
4、RedirectView
“RedirectView”是重定向视图。
例如,当用户访问“http://127.0.0.1:8888/django2”时,页面跳转到“http://www.opython.com/django2”。
示例代码:
from django.views.generic.base import RedirectView
path('django2/',RedirectView.as_view(url='http://www.opython.com/django2/'),name='django2'),
这个视图我们也可以通过创建子类重写某些内容,实现更多的重定向功能。
本文链接:http://so.lmcjl.com/news/2250/