一 路由系统进阶(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进阶-路由,视图,模板的更多相关文章

  1. 2016/5/6 thinkphp ①框架 ② 框架项目部署 ③MVC模式 ④控制器访问及路由解析 ⑤开发和生产模式 ⑥控制器和对应方法创建 ⑦视图模板文件创建 ⑧url地址大小写设置 ⑨空操作空控制器 ⑩项目分组

    真实项目开发步骤: 多人同时开发项目,协作开发项目.分工合理.效率有提高(代码风格不一样.分工不好) 测试阶段 上线运行 对项目进行维护.修改.升级(单个人维护项目,十分困难,代码风格不一样) 项目稳 ...

  2. angular.js的路由和模板在asp.net mvc 中的使用

    angular.js的路由和模板在asp.net mvc 中的使用 我们知道angular.js是基于mvc 的一款优秀js框架,它也有一套自己的路由机制,和asp.net mvc 路由不太一样.as ...

  3. AngularJS 路由和模板实例及路由地址简化方法

    最近一同事在学习AngularJS,在路由与模板的学习过程中遇到了一些问题,于是今天给她写了个例子,顺便分享出来给那些正在学习AngularJS的小伙伴们. 话说这AngularJs 开发项目非常的爽 ...

  4. Laravel教程 二:路由,视图,控制器工作流程

    Laravel教程 二:路由,视图,控制器工作流程 此文章为原创文章,未经同意,禁止转载. View Controller 上一篇教程我们走了那么长的路,终于把Laravel安装好了,这一篇教程我们就 ...

  5. PHP Lavavel 使用控制器 传递变量 以及调用 视图模板

    控制器第一次入门使用 位置: 在app/Http/Controllers 目录下创建文件名格式:例如 UserController路由调用格式:Route::get('user/tom','UserC ...

  6. 【7】Django网页视图模板处理

    天下难事必作於易.天下大事必作於细.是以圣人终不为大,故能成其大 --老子<道德经> 本节内容 HTML页面的渲染 使用页面模板 异常处理 超链接路径处理 路由命名空间 1. HTML页面 ...

  7. vue 路由视图,router-view嵌套跳转

    实现功能:制作一个登录页面,跳转到首页,首页包含菜单栏.顶部导航栏.主体,标准的后台网页格式.菜单栏点击不同菜单控制主体展示不同的组件(不同的页面). 配置router-view嵌套跳转需要准备两个主 ...

  8. Solon Web 开发,七、视图模板与Mvc注解

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  9. AspNet MVC与T4,我定制的视图模板

    一. 遇到的问题 文章开头部分想先说一下自己的困惑,在用AspNet MVC时,完成Action的编写,然后添加一个视图,这个时候弹出一个添加视图的选项窗口,如下: 很熟悉吧,继续上面说的,我添加一个 ...

随机推荐

  1. 20190809-RP?不存在的

    火苗静静的将世界荡涤. ??? 毁灭它,点亮它. 只发光不放热? 那是虚无, ……还有你我的遗言. 考试过程. 通看三题. 额嗯嗯,没想法. T1写个暴力吧. T2好像挺简单. T3好像还行?? T1 ...

  2. Linux学习(一):软链接和硬链接

    今天起,决定开始自学Linux命令及Shell脚本,并用Linux学习(命令行,Shell及其他知识点)这一系列记录下自己的心路历程,内容不分先后,只记录自己觉得有必要的,简单的就不记了! 第一个知识 ...

  3. Java借助itext pdf生成固定格式pdf的模板工具类

    这里是标题区域 这里是副标题1: 副标题的内容 这里是副标题2: 这里是副标题2的内容 这里是副标题3: 这里是副标题3的内容 序号 表头1 复合表头 表头2 子表头1 子表头2 子表头3 1 居左内 ...

  4. 【同余最短路】【例题集合】洛谷P3403 跳楼机/P2371 墨墨的等式

    接触到的新内容,[同余最短路]. 代码很好写,但思路不好理解. 同余最短路,并不是用同余来跑最短路,而是通过同余来构造某些状态,从而达到优化时间空间复杂度的目的.往往这些状态就是最短路中的点,可以类比 ...

  5. oracle-表空间-用户-角色-权限

    概要图 概要图 一 表空间 1.1创建表空间 --问题:创建一个名为hp的表空间,指定数据文件为hp.dbf,大小为10m. create tablespace hp datafile 'C:\app ...

  6. spring和mybatis整合遇到org.springframework.beans.factory.BeanDefinitionStoreException

    今天对spring和mybatis整合进行练习,通过MapperScannerConfigurer进行mapper扫描 但是在进行单元测试的时候,死活就是报错,具体报错如下: org.springfr ...

  7. Hdu 1269 强连通判定

    题目链接 迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  8. java路径中'/'的使用

    考虑java的跨系统:uinux和winw7中的‘/'标识方法不同,使用下放语句可避免 File.separator;//代表"/"

  9. 第三十一讲:UML类图(上)

    类名 成员变量:属性 成员函数:方法 访问权限-属性名-属性的类型 访问权限-方法名-返回值,还可以传递参数列表. 继承类的类图 JAVA里面类的访问权限只有两种:package(默认的访问权限)和p ...

  10. 单行中文字和图片的相关height和line-height特性

    这几天在做仿京东的产品页,发现在制作过程中的一些问题,需要好好研究下. 需要实现的效果如上图所示: 在写CSS样式的时候,对于我的关于竖线的做法是: 设置高度为14,border样式,但导致了一个问题 ...