17-1 djanjo进阶-路由,视图,模板
一 路由系统进阶(urls.py)
动态路由
urls.py中通过正则表达式的分组匹配,捕获用户访问的url中的值,传递给视图函数
1 分组匹配(通过圆括号):
相当于给视图函数传递 位置参数
例子:
- from django.conf.urls import url
- from . import views
- urlpatterns = [
- url(r'^articles/2003/$', views.special_case_2003),
- url(r'^articles/([0-9]{4})/$', views.year_archive),
- url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
- url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
- ]
2 分组命名匹配:
相当于给视图函数传递 关键字参数
在Python的正则表达式中,分组命名正则表达式组的语法是(?P<name>pattern)
,其中name
是组的名称,pattern
是要匹配的模式。
例子:
- from django.conf.urls import url
- from . import views
- urlpatterns = [
- url(r'^articles/2003/$', views.special_case_2003),
- url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
- url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
- url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
- ]
3 name
防止将url硬编码到我们的业务逻辑代码中,给url起别名
通过别名,反向找到 url
配置:
在views.py中:
from django.urls import reverse
具体的url = reverse('url别名')
例子:
urls.py里面配置:
url(r'^publisher_list/$', views.publisher_list, name="alex")
vivews.py引用:
- # def edit_publisher(request, edit_id):
- # print(reverse('alex'))
- # print("=" * 120)
- # if request.method == "POST":
- # new_name = request.POST.get("name888")
- # # 去数据库修改出版社名字
- # obj = models.Publisher.objects.get(id=edit_id)
- # obj.name = new_name
- # obj.save()
- # return redirect(reverse('alex')) #返回一个url
- # print(edit_id)
- # publisher_obj = models.Publisher.objects.get(id=edit_id)
- # return render(request, "edit_publisher.html", {"obj": publisher_obj})
4 传参数的两种写法(一不小心就被坑了)
例子一:url传参
1 urls.py配置:
- url(r'^edit_publisher/$', views.edit_publisher),
2 views.py
- def edit_publisher(request):
if request.method=="POST":- #获取用户更改的id
- edit_id=request.POST.get("id")#从浏览器传的参数获取的id
- new_name=request.POST.get("name")#从form表单获取的名字
- #去数据库找到这条记录
- obj=models.Publisher.objects.get(id=edit_id)
- obj.name=new_name
- obj.save()
- return redirect("/publisher_list/")
- else:
- edit_id = request.GET.get("id")
- publisher_edit = models.Publisher.objects.get(id=edit_id)
- return render(request,"edit_publisher.html",{"obj":publisher_edit})
注意:#上面红色字体里面的的obj一定要和你相应的edit_publisher里面的value,里面的一致,比如value=obj.name 这里就一定用obj
3 html配置:
publisher_list.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>出版社列表</title>
- <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
- </head>
- <body>
- <div class="container">
- <div class="row">
- <div class="col-md-8 col-sm-offset-2">
- <table class="table table-bordered">
- <tr>
- <th>#</th>
- <th>id</th>
- <th>出版社名字</th>
- <th>操作</th>
- </tr>
- {# data这里一定要跟views里面的data一样#}
- {% for publisher in data %}
- <tr>
- <td>{{ forloop.counter }}</td>
- <td>{{ publisher.id }}</td>
- <td>{{ publisher.name }}</td>
- <td>
- {# 这是动态传参#}
- {# <a href="/edit_publisher/{{ publisher.id }}/" class="btn btn-info">编辑</a>#}
- {# 这是浏览器传参数#}
- <a href="/edit_publisher/?id={{ publisher.id }}" class="btn btn-info">编辑</a>
- <a href="/del_publisher" class="btn btn-info">删除</a>
- </td>
- </tr>
- {% endfor %}
- </table>
- </div>
- </div>
- </div>
- </body>
- </html>
edit_publisher.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>编辑</title>
- <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
- </head>
- <body>
- <form class="form-horizontal" action="" method="post">
- <input type="text" name="id" value="{{ obj.id }}" style="display: none">
- <div class="form-group">
- <label for="inputEmail3" class="col-sm-2 control-label">出版社名称</label>
- <div class="col-sm-10">
- <input type="text" class="form-control" name="name" value="{{ obj.name }}" id="inputEmail3"
- placeholder="新名称">
- </div>
- </div>
- <div class="form-group">
- <div class="col-sm-offset-2 col-sm-10">
- <button type="submit" class="btn btn-default">提交</button>
- </div>
- </div>
- </form>
- </body>
- </html>
例子二 动态传参
1 urls配置:
- url(r'^edit_publisher/(\d+)/$', views.edit_publisher),
2 views.py配置
- # def edit_publisher(request,edit_id):
- # if request.method=="POST":
- # #获取用户更改的id
- #
- # new_name=request.POST.get("name")#从form表单获取的名字
- # #去数据库找到这条记录
- # obj=models.Publisher.objects.get(id=edit_id)
- # print(obj.name)
- # obj.name=new_name
- # obj.save()
- # return redirect("/publisher_list/")
- # else:
- #
- # publisher = models.Publisher.objects.get(id=edit_id)
- # return render(request,"edit_publisher.html",{"obj":publisher})
3 html配置:
publisher_list.html
- <a href="/edit_publisher/{{ publisher.id }}/" class="btn btn-info">编辑</a>
edit_publisher.html不变
二 视图函数进阶(views.py)
1. 1-views.py
1.基础必会三件套
1. HttpResponse('字符串')
2. render(request, "xx.html", {"key": value})
3. redirect("/其它的url/")
2. FBV(Function Base View) 基于函数的视图
通过request.method == "POST" 去判断
例子:
- # def edit_publisher(request, edit_id):
- # print(reverse('alex'))
- # print("=" * 120)
- # if request.method == "POST":
- # new_name = request.POST.get("name888")
- # # 去数据库修改出版社名字
- # obj = models.Publisher.objects.get(id=edit_id)
- # obj.name = new_name
- # obj.save()
- # return redirect(reverse('alex'))
- # print(edit_id)
- # publisher_obj = models.Publisher.objects.get(id=edit_id)
- # return render(request, "edit_publisher.html", {"obj": publisher_obj})
3. CBV(Class Base View) 基于类的视图
1. 必须继承views.View -->在views.py里面导入: from django import views
2. 写一个自己的视图类
3. 通过定义不同的方法,来处理用户不同的请求
4. 在urls.py中注册视图的时候要写 views.类名.as_view()
urls.py中配置:
- url(r'^edit_publisher/(?P<edit_id>\d+)/$', views.EditPublisher.as_view(), name="wusir"),
view.py配置:
例子:
- class EditPublisher(views.View):
- def get(self, request, edit_id):
- publisher_obj = models.Publisher.objects.get(id=edit_id)
- return render(request, "edit_publisher.html", {"obj": publisher_obj})
- def post(self, request, edit_id):
- new_name = request.POST.get("name888")
- # 去数据库修改出版社名字
- obj = models.Publisher.objects.get(id=edit_id)
- obj.name = new_name
- obj.save()
- return redirect(reverse('alex'))
2.1 request对象的常用属性和方法(常用的几个)
request表示的是和用户请求相关的所有数据
1. request.method --> 用户当前请求的请求方法
2. request.GET --> 用户请求中url中的参数
3. request.POST --> 用户POST请求的数据
4. request.path_info --> 用户访问的url路径是什么
3.1 Django上传文件
1. 前端页面
1. form表单一定要有action,method必须是post
2. 一定要配置enctype="multipart/form-data
2. 后端:
- def upload(request):
- """
- 保存上传文件前,数据需要存放在某个位置。默认当上传文件小于2.5M时,django会将上传文件的全部内容读进内存。从内存读取一次,写磁盘一次。
- 但当上传文件很大时,django会把上传文件写到临时文件中,然后存放到系统临时文件夹中。
- :param request:
- :return:
- """
- if request.method == "POST":
- # 从请求的FILES中获取上传文件的文件名,file为页面上type=files类型input的name属性值
- filename = request.FILES["file"].name
- # 在项目目录下新建一个文件
- with open(filename, "wb") as f:
- # 从上传的文件对象中一点一点读
- for chunk in request.FILES["file"].chunks():
- # 写入本地文件
- f.write(chunk)
- return HttpResponse("上传OK")
4.1 JsonResponse
专门用来返回JSON格式数据的响应对象
from django.http import JsonResponse
例子:
- from django.http import JsonResponse
- response = JsonResponse({'foo': 'bar'})
- print(response.content)
- b'{"foo": "bar"}'
默认只能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。
例子:
- urls.py
- url(r'^json_test/$', views.JsonTest.as_view()),
- views.py
- class JsonTest(views.View):
- def get(self, request):
- res = {"code": 0, "data": "alex"}
- res2 = ["alex", "污Sir", "金老板", "小姨妈", "MJJ"]
- return JsonResponse(res2,safe=False)
三 模板引擎进阶
1 模板语法:
1. 两个语法:
1. {{ }} --> 跟变量相关的操作
2. {% %} --> 跟逻辑相关的操作
2. 变量相关
1. 传字典或对象类型的数据 obj.name/obj.age
2. 传数组类型的数据 obj.索引值
例子:
- def template_test(request):
- l = [11, 22, 33]
- d = {"name": "alex"}
- class Person(object):
- def __init__(self, name, age):
- self.name = name
- self.age = age
- def dream(self):
- return "{} is dream...".format(self.name)
- Alex = Person(name="Alex", age=34)
- Egon = Person(name="Egon", age=9000)
- Eva_J = Person(name="Eva_J", age=18)
- person_list = [Alex, Egon, Eva_J]
- return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})
取值:
- {# 取l中的第一个参数 #}
- {{ l.0 }}
- {# 取字典中key的值 #}
- {{ d.name }}
- {# 取对象的name属性 #}
- {{ person_list.0.name }}
- {# .操作只能调用不带参数的方法 #}
- {{ person_list.0.dream }}
3. 日期格式化
<p>{{ today|date:"Y-m-d H:i:s"}}</p>
4. 显示真正的html代码
<p>{{ link|safe }}</p>
例子:
view配置:
- def template_test(request):
- data = ["金老板", "景女神", "MJJ"]
- # data = ""
- filesize = 1234567890
- import datetime
- today = datetime.datetime.today()
- link = "<script>for(;;){alert(123)}</script>"
- class Person(object):
- def __init__(self, name, dream):
- self.name = name
- self.dream = dream
- def dream(self):
- return "我的梦想是学好Python!"
- pw = Person("彭玮", "不去下一期!")
- return render(request, "t.html", {
- "data": data,
- "file_size": filesize,
- "today": today,
- "link": link,
- "person": pw
- })
html中配置:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- {#<p>{{ data.1 }}</p>#}
- <p>{{ data|default:"暂无数据" }}</p>
- <p>{{ file_size|filesizeformat }}</p>
- <p>{{ today }}</p>
- <p>{{ link }}</p>
- {#<p>{{ link|safe }}</p>#}
- <hr>
- <p>
- {% for teacher in data %}
- {% if forloop.last %}
- {{ teacher }}
- {% else %}
- {{ teacher }},
- {% endif %}
- {% endfor %}
- </p>
- {#<p>{% if 3 > 2 > 1 %}{% endif %}</p>#}(不支持这样写)
- {##}
- {#<p>{% if 3 > 2 and 2 > 1 %}{% endif %}</p>#}
- <hr>
- {{ person.name }}
- {{ person.dream }}
- </body>
- </html>
2. 母板
1. 为什么要用母版?
不同的页面有大量重复的代码,我们可以把公用的部分提取出来放在单独一个文件
2. 怎么使用?
1.1. 在子页面 通过使用 {% extends ‘模板名’ %} --> 放在子页面的最上面
2. 1{% block xx %}{% endblock %}
母版例子:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>{{ html_title }}</title>
- <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css">
- {% block page-css %}
- {% endblock %}
- </head>
- <body>
- {% include 'nav.html' %}
- <div class="container">
- <div class="row">
- <div class="col-md-8 col-md-offset-2">
- {% block page-main %}
- {% endblock %}
- </div>
- </div>
- </div>
- <script src="/static/jquery.js"></script>
- {% block page-js %}
- {% endblock %}
- </body>
- </html>
3. 组件
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。
使用 {% include '组件名' %}导入
如何继承母版例子:
- {% extends 'mama.html' %}
- {% block page-main %}
- <table class="table table-bordered">
- <thead>
- <tr>
- <th>#</th>
- <th>id</th>
- <th>出版社名称</th>
- <th>操作</th>
- </tr>
- </thead>
- <tbody>
- {% for publisher in publisher_list %}
- <tr>
- <td>{{ forloop.counter }}</td>
- <td>{{ publisher.id }}</td>
- <td>{{ publisher.name }}</td>
- <td>
- <a href="/edit_publisher/{{ publisher.id }}/" class="btn btn-info">编辑</a>
- <a href="/delete_publisher/" class="btn btn-danger">删除</a>
- </td>
- </tr>
- {% endfor %}
- </tbody>
- </table>
- {% endblock %}
- {#我这个页面才用到的一个js文件#}
- {% block page-js %}
- <script src="/static/1.js"></script>
- {% endblock %}
四 CSRF
1. 为什么要有csrf_token?
2. Django中如何使用?
在render的页面上写上{% csrf_token %}
3. 如果是form表单形式提交,必须放在form表单中
4 如果不加csrf_token默认是不让提交的报403错误
例子:
urls.py配置
url(r'^csrf_test/$', views.csrf_test),
views.py配置:
- def csrf_test(request):
- if request.method=="POST":
- print(request.POST)
- return HttpResponse("OK")
- else:
- return render(request,"csrf_test.html")
html配置:
- <form action="" method="post">
- {% csrf_token %}
- <input type="text" name="name">
- <input type="submit" value="提交">
- </form>
17-1 djanjo进阶-路由,视图,模板的更多相关文章
- 2016/5/6 thinkphp ①框架 ② 框架项目部署 ③MVC模式 ④控制器访问及路由解析 ⑤开发和生产模式 ⑥控制器和对应方法创建 ⑦视图模板文件创建 ⑧url地址大小写设置 ⑨空操作空控制器 ⑩项目分组
真实项目开发步骤: 多人同时开发项目,协作开发项目.分工合理.效率有提高(代码风格不一样.分工不好) 测试阶段 上线运行 对项目进行维护.修改.升级(单个人维护项目,十分困难,代码风格不一样) 项目稳 ...
- angular.js的路由和模板在asp.net mvc 中的使用
angular.js的路由和模板在asp.net mvc 中的使用 我们知道angular.js是基于mvc 的一款优秀js框架,它也有一套自己的路由机制,和asp.net mvc 路由不太一样.as ...
- AngularJS 路由和模板实例及路由地址简化方法
最近一同事在学习AngularJS,在路由与模板的学习过程中遇到了一些问题,于是今天给她写了个例子,顺便分享出来给那些正在学习AngularJS的小伙伴们. 话说这AngularJs 开发项目非常的爽 ...
- Laravel教程 二:路由,视图,控制器工作流程
Laravel教程 二:路由,视图,控制器工作流程 此文章为原创文章,未经同意,禁止转载. View Controller 上一篇教程我们走了那么长的路,终于把Laravel安装好了,这一篇教程我们就 ...
- PHP Lavavel 使用控制器 传递变量 以及调用 视图模板
控制器第一次入门使用 位置: 在app/Http/Controllers 目录下创建文件名格式:例如 UserController路由调用格式:Route::get('user/tom','UserC ...
- 【7】Django网页视图模板处理
天下难事必作於易.天下大事必作於细.是以圣人终不为大,故能成其大 --老子<道德经> 本节内容 HTML页面的渲染 使用页面模板 异常处理 超链接路径处理 路由命名空间 1. HTML页面 ...
- vue 路由视图,router-view嵌套跳转
实现功能:制作一个登录页面,跳转到首页,首页包含菜单栏.顶部导航栏.主体,标准的后台网页格式.菜单栏点击不同菜单控制主体展示不同的组件(不同的页面). 配置router-view嵌套跳转需要准备两个主 ...
- Solon Web 开发,七、视图模板与Mvc注解
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- AspNet MVC与T4,我定制的视图模板
一. 遇到的问题 文章开头部分想先说一下自己的困惑,在用AspNet MVC时,完成Action的编写,然后添加一个视图,这个时候弹出一个添加视图的选项窗口,如下: 很熟悉吧,继续上面说的,我添加一个 ...
随机推荐
- g++编译多个源原文件和头文件(转载)
(头文件名是:Sales_item.hpp 源文件名:7-31.cpp和Sales_item.cpp)(点击我下载源文件) 方法1: 我用的命令是:g++ -o 7-31 7-31.cpp Sales ...
- sass进阶
代码的重用 基础的部分我们讲述了变量 Mixin 这两种方法可以增加扩展和重用 现在开始继续学习:extend继承 .class1 { border: 1px solid #ddd; } .class ...
- Pycharm 2018激活(Mac版)
第一步,修改host文件 目的:是屏蔽掉Pycharm对激活码的验证 路径:/etc/hosts 在文件最后一行添加文本: 0.0.0.0 account.jetbrains.com 修改后文件如下: ...
- GIT → 02:Git和Svn比较
2.1 SVN介绍 2.1.1 SVN简介 SVN 属于集中式版本管理控制系统,服务器中保存了所有文件的不同版本,而协同工作人员通过连接svn服务器,提取出最新的文件,获取提交更新.Subversio ...
- 2018-8-10-如何移动-nuget-缓存文件夹
title author date CreateTime categories 如何移动 nuget 缓存文件夹 lindexi 2018-08-10 19:16:51 +0800 2018-2-13 ...
- Javascript-商品管理新增/删除/修改功能
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- TSQL:让监控分析更简单更高效
1. 前言 阿里时序时空数据库TSDB最新推出TSQL,支持标准SQL的语法和函数.用户使用熟悉的SQL,不仅仅查询更简单易用,用户还可以利用SQL强大的功能,实现更加复杂的计算分析. 2. 为什么需 ...
- Django项目:CRM(客户关系管理系统)--03--02PerfectCRM创建ADMIN页面01
八.CRM项目创建king_admin python.exe manage.py startapp king_admin 'king_admin', 九.CRM项目分发URL "" ...
- 【Mobius绮丽的辗转】莫比乌斯反演
Problem 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 1≤n≤50000,1≤a≤b≤5 ...
- JPA 将驼峰列名自动转换为_
数据库中和代码中都没有'cat_age'列名:但是用jpa保存的时候,总是提示此错误:这个问题纠结半天,后来在朋友的指点下,找到问题所在: spring data jpa 使用默认策略是Improv ...