一 路由系统进阶(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. light oj 1427(ac自动机)

    #include <bits/stdc++.h> using namespace std; *; ; map<string,int>Map; struct Trie { int ...

  2. 读书笔记--Head First Networking目录

    1.解决物理网络 2.规划网络布局 3.工具和故障排除 4.包分析 5.网络设备和流量 6.连接网络的路由器 7.路由协议 8.域名系统 9.监控和故障排除 10.无线网络 11.网络安全 12.网络 ...

  3. POSTMAN调试接口post对象

    APP回传设备信息,设备信息对象里边包含以下字段 后台是java ssh接收 用对象属性自动封装比较方便 所以,使用 方式进行回传 而不是使用网上说的 设置如下图

  4. Sql server定时执行某个sql 通过Windows 计划任务(非代理Job方式)

    建立 bat文件.内容如下: osql -s "xxx.xxx.xx.x" -U sa -P sa -d DB -i TruncateSql.sql osql -S "l ...

  5. pycharm多行批量缩进和反向缩进快捷键

    在 VS, PYCHARM 中只要 拉选块之后,按下tab键,整个块就会缩进 按下 shift + tab 就会反向缩进

  6. git命令入门

    http://www.cocoachina.com/ios/20160629/16855.html 译者序:这是一篇给像我这样的新手或者是熟悉图形工具的老鸟看的.仅作为快速入门的教程. git 现在的 ...

  7. Oracle 定义变量总结

    首先,当在cmd里办入scott密码提示错误时,可以这样改一下,scott的解锁命令是: 以system用户登录:cmdsqlplus system/tigertigeralter user scot ...

  8. C++之ARX 读取配置文件内容时,会出现编码问题(utf-8转unicode)

    CString CConvert::UTF82WCS(const char* szU8){ //预转换,得到所需空间的大小; int wcsLen = ::MultiByteToWideChar(CP ...

  9. 2019-4-29-dotnet-core-通过-frp-发布自己的网站

    title author date CreateTime categories dotnet core 通过 frp 发布自己的网站 lindexi 2019-04-29 12:26:45 +0800 ...

  10. windows.open window.location.href的用法和区别

    window.location.href  只能在当前页面打开,不能用新窗口打开 windows.open("URL","窗口名称","窗口外观设定& ...