django进阶-1
前言: 各位久等了,django进阶篇来了。
一、get与post
接口规范: url不能写动词,只能写名词
django默认只支持两种方式: get, post
get是获取数据
- ?user=zcl&password=abc&email=669@qq
?号表示后面是参数,&在两参数中间
- request.GET.get("password")
上面这句代码可获取密码abc,是明文的!!
post获取密码是密文的。post请求用于创建或修改数据。
- if request.method == 'GET':
- # <view logic>
- return HttpResponse('result')
二、模版渲染
你可能已经注意到我们在例子视图中返回文本的方式有点特别。 也就是说,HTML被直接硬编码在 Python 代码之中。
- def current_datetime(request):
- now = datetime.datetime.now()
- html = "<html><body>It is now %s.</body></html>" % now
- return HttpResponse(html)
尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好主意。 让我们来看一下为什么:
- 对页面设计进行的任何改变都必须对 Python 代码进行相应的修改。 站点设计的修改往往比底层 Python 代码的修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。
- Python 代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。
- 程序员编写 Python代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。
基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的 模板系统 (Template System)来实现这种模式。
Django模版基本语法
- >>> from django.template import Context, Template
- >>> t = Template('My name is {{ name }}.')
- >>> c = Context({'name': 'Stephane'})
- >>> t.render(c)
- u'My name is Stephane.'
同一模板,多个上下文: 一旦有了 模板 对象,你就可以通过它渲染多个context
- >>> from django.template import Template, Context
- >>> t = Template('Hello, {{ name }}')
- >>> print t.render(Context({'name': 'John'}))
- Hello, John
- >>> print t.render(Context({'name': 'Julie'}))
- Hello, Julie
- >>> print t.render(Context({'name': 'Pat'}))
- Hello, Pat
无论何时我们都可以像这样使用同一模板源渲染多个context,只进行 一次模板创建然后多次调用render()方法渲染(render)会更为高效:
- # Bad
- for name in ('John', 'Julie', 'Pat'):
- t = Template('Hello, {{ name }}')
- print t.render(Context({'name': name}))
- # Good 生成模版实例是有系统开销的,一个模版实例是可以进行多次上下文的渲染
- t = Template('Hello, {{ name }}')
- for name in ('John', 'Julie', 'Pat'):
- print t.render(Context({'name': name}))
注意: 如果没有python manage.py shell 是会曝错的!!这句代码的意义是导入django环境。
三、深度变量的查找
在到目前为止的例子中,我们通过 context 传递的简单参数值主要是字符串,然而,模板系统能够非常简洁地处理更加复杂的数据结构,例如list、dictionary和自定义的对象。
在 Django 模板中遍历复杂数据结构的关键是句点字符 (.)。
向模板传递一个 Python 字典。 要通过字典键访问该字典的值,可使用一个句点:
- >>> from django.template import Template, Context
- >>> person = {'name': 'Sally', 'age': ''}
- >>> t = Template('{{ person.name }} is {{ person.age }} years old.')
- >>> c = Context({'person': person})
- >>> t.render(c)
- u'Sally is 43 years old.'
同样,也可以通过句点来访问对象的属性。 比方说, Python 的 datetime.date 对象有 year 、 month 和 day 几个属性,你同样可以在模板中使用句点来访问这些属性:
- >>> from django.template import Template, Context
- >>> import datetime
- >>> d = datetime.date(1993, 5, 2)
- >>> d.year
- 1993
- >>> d.month
- 5
- >>> d.day
- 2
- >>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')
- >>> c = Context({'date': d})
- >>> t.render(c)
- u'The month is 5 and the year is 1993.'
句点也可用于访问列表索引,例如:
- >>> from django.template import Template, Context
- >>> t = Template('Item 2 is {{ items.2 }}.')
- >>> c = Context({'items': ['apples', 'bananas', 'carrots']})
- >>> t.render(c)
- u'Item 2 is carrots.'
四、隔行更换背景颜色
效果图(太牛啦):
输入url通过路由调用index方法:
- def index(request):
- if request.method == "GET":
- user_info = [{"username":"zcl_1","name":"zhang CL",},
- {"username": "zcl_2", "name": "zhang CL", },
- {"username": "zcl_3", "name": "zhang CL", },
- {"username": "zcl_4", "name": "zhang CL", },
- {"username": "zcl_5", "name": "zhang CL", },]
- return render(request, "app01/index.html", {"user_objs":user_info})
app01/index.html下部分代码:
- <ul>
- {% for user_obj in user_objs %}
- {# {% if forloop.counter0 > 2 %}#}
- {% if forloop.counter0|divisibleby:"2" %}
- <li style="background-color: darksalmon">username:{{ user_obj.username }};name:{{ user_obj.name }}</li>
- {% else %}
- <li style="">username:{{ user_obj.username }};name:{{ user_obj.name }}</li>
- {% endif %}
- {% endfor %}
- </ul>
注意: forloop.counter0表示循环从0开始,divisibleby:"2"表示能被2整除的。PS: 千万不要写成divisibleby: "2"(中间加个空格,会曝错的!!当时我就加了空格,出错时一脸懵比...)
五、模版的继承与复用
Templates/app01/page1.html文件:
- <body>
- {% extends "app01/index.html" %} {#继承父模版#}
- <h1>page1</h1>
- </body>
- Templates/app01/index.html文件:
- <body>
- <ul>
- <li style="display: inline">Home</li>
- <li style="display: inline">page1</li>
- <li style="display: inline">page2</li>
- <li style="display: inline">page3</li>
- </ul>
- <h1>welcome to payment index</h1>
- <footer>
- <h1>foot</h1>
- </footer>
- </body>
Templates/app01/index.html文件:
- <body>
- <ul>
- <li style="display: inline">Home</li>
- <li style="display: inline">page1</li>
- <li style="display: inline">page2</li>
- <li style="display: inline">page3</li>
- </ul>
- <h1>welcome to payment index</h1>
- <footer>
- <h1>foot</h1>
- </footer>
- </body>
渲染page1.html文件效果图:
问题: 发现虽然可以继承父模版index.html,但是子模版page1.html的内容被覆盖。默认全部继承父模版!!
如何解决这个问题呢? 实际需求上,比如一个网站的上方菜单栏,前端界面基本是一样的,不同页面会有微小的不同。这时我想,我可以做一个网站的菜单栏作为父模版,该父模版可以被其它页面继承(extends)或复用(include).
现在我有个需求,我只想替换父模版index.html的 welcome to payment index:
Templates/app01/index.html文件:用block将需要被替换的内容包含起来。
- {% block content-container %}
- <h1>welcome to payment index</h1>
- {% endblock %}
Templates/app01/page1.html文件: 用block将要替换父模版的内容包含起来。
- <body>
- {% extends "app01/index.html" %}
- {% block content-container %} {# 重写父模版的content-container部分 #}
- <h1>page1</h1>
- {% endblock %}
- </body>
继承效果图:
复用就简单了,重复地使用嘛,比如我在register.html写一个注册的表单,只要网站的页面有需要注册,直接复用之前写的表单就OK了
- {% include "app01/register.html" %}
Templates/app01/page1.html文件:
- <body>
- {% extends "app01/index.html" %}
- {% block content-container %}
- <h1>page1</h1>
- {% include "app01/register.html" %}
- {% endblock %}
- </body>
Templates/app01/register.html:
- <body>
- <div style="background-color: antiquewhite">
- <form>
- Username:<input name="username" type="text">
- Password:<input name="password" type="password">
- </form>
- </div>
- </body>
继承+复用效果图(图中form表单是复用来的~):
六、django orm
django 本身提供了非常强大易使用的ORM组件,并且支持多种数据库,如sqllite,mysql,progressSql,Oracle等,当然最常用的搭配还是mysql,要启用orm,先要配置好连接数据 的信息。
为了更好的理解,我们来做一个基本的 书籍/作者/出版商 数据库结构。 我们这样做是因为 这是一个众所周知的例子,很多SQL有关的书籍也常用这个举例。
我们来假定下面的这些概念、字段和关系:
一个作者有姓,有名及email地址。
出版商有名称,地址,所在城市、省,国家,网站。
书籍有书名和出版日期。 它有一个或多个作者(书和作者是多对多的关联关系[many-to-many]), 只有一个出版商(书和出版商是一对多的关联关系[one-to-many],也被称作外键[foreign key])
第一步:在配置文件加入app名(我创建的app名为app01)
第二步: 我mysqldb装不上,为了方便用默认的sqllite数据库~
用默认的sqlite数据库,就啥都不用改,直接看第三步;当然如果你mysqldb模块装上了,可以用mysql数据库试试,可在settings.py改下数据库连接的配置:
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.mysql',
- 'NAME': 'OldboyWebsite', #确保此数据库已存在
- 'HOST':'',
- 'PORT':'',
- 'USER':'root',
- 'PASSWORD':''
- }
- }
第三步: 创建表结构
- from django.db import models
- # Create your models here.
- class Author(models.Model):
- first_name = models.CharField(max_length=32)
- last_name = models.CharField(max_length=32)
- email = models.EmailField()
- def __str__(self):
- return "<%s %s>" % (self.first_name,self.last_name)
- class Meta:
- verbose_name_plural = u"作者"
- class Publisher(models.Model):
- name = models.CharField(max_length=64, unique=True)
- address = models.CharField(max_length=128,null=True,blank=True)
- city = models.CharField(max_length=64)
- state_province = models.CharField(max_length=64,help_text="put your province here",verbose_name=u"所属省")
- country = models.CharField(max_length=64,editable=False)
- website = models.URLField()
- def __str__(self):
- return "<%s>" % (self.name)
- class Book(models.Model):
- name = models.CharField(max_length=128)
- authors = models.ManyToManyField(Author) #书多对多到作者
- publisher = models.ForeignKey(Publisher) #一对多
- publish_date = models.DateField() #精确到天DateField()
- def __str__(self):
- return "<%s %s>" % (self.name,self.publisher)
看上面的代码,如果你看过我之前的博客sqlalchemy orm和堡垒机表结构设计,就会发现django orm进行多对多关联时不用自己来生成中间表,天呐!!这可方便了!!
你可能看不懂上面的help_text,verbose_name,editable,class Meta:,def __str__(self):.....这些我等下讲,慢慢来,一下子就高潮就不好了哈哈。
第四步: 为了能在django后台的管理员能查看到生成的表,在app01/admin.py文件添加下面代码:
第五步: 同步数据库
第六步: 创建superuser
第七步: 登陆admin并创建数据
注意: 在创建表结构时,如果不在表对象中加入def __str__(self):方法(python3下),则会出现下面情况:无法显示出书的名称。 Python2对应为def __unicode__(self):
model field
模型字段我这里讲几个意思意思就好了,更多的请参考官方文档。
更多models field 字段:https://docs.djangoproject.com/en/1.9/ref/models/fields/
1. null & blank
- address = models.CharField(max_length=128,null=True)
在出版社表的address字段加上null = True; 此时address在admin后台仍不能为空!
必须再加上bland = True; 限制django admin可为空。
六级没过的我,差15分……来看段官方英文热热身……只要你看得懂,会发现英文真TM易懂,因为英文不会有歧义。
2. editable = False 表示不能更改
我大天朝的国籍企是你想改就能改的……
- country = models.CharField(max_length=64,editable=False)
3. help_text = "xx" 提示文字 不是对数据库的修改,是对django admin页面的修改,所以当你增加这个字段,你是不用去同步数据库的。
- state_province = models.CharField(max_length=64,help_text="put your province here")
4. verbose_name 详细的名字
- state_province = models.CharField(max_length=64,help_text="put your province here",verbose_name=u"所属省")
5. class Meta: 如果想自己在django后台定义表名,可在表结构加上下面的代码:
- class Meta:
- verbose_name_plural = u"作者"
七、增删改查
上图!!
查找类型有:icontains(大小写不敏感的LIKE),startswith和endswith, 还有range
关于修改,有个点要注意下:
更新多个对象
在“插入和更新数据”小节中,我们有提到模型的save()方法,这个方法会更新一行里的所有列。 而某些情况下,我们只需要更新行里的某几列。
例如说我们现在想要将Apress Publisher的名称由原来的”Apress”更改为”Apress Publishing”。若使用save()方法,如:
- >>> p = Publisher.objects.get(name='Apress')
- >>> p.name = 'Apress Publishing'
- >>> p.save()
这等同于如下SQL语句:
- SELECT id, name, address, city, state_province, country, website
- FROM books_publisher
- WHERE name = 'Apress';
- UPDATE books_publisher SET
- name = 'Apress Publishing',
- address = '2855 Telegraph Ave.',
- city = 'Berkeley',
- state_province = 'CA',
- country = 'U.S.A.',
- website = 'http://www.apress.com'
- WHERE id = 52;
(注意在这里我们假设Apress的ID为52)
在这个例子里我们可以看到Django的save()方法更新了不仅仅是name列的值,还有更新了所有的列。 若name以外的列有可能会被其他的进程所改动的情况下,只更改name列显然是更加明智的。 更改某一指定的列,我们可以调用结果集(QuerySet)对象的update()方法: 示例如下:
- >>> Publisher.objects.filter(id=52).update(name='Apress Publishing')
与之等同的SQL语句变得更高效,并且不会引起竞态条件。
- UPDATE books_publisher
- SET name = 'Apress Publishing'
- WHERE id = 52;
update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录。 以下示例演示如何将所有Publisher的country字段值由’U.S.A’更改为’USA’:
- >>> Publisher.objects.all().update(country='USA')
- 2
连锁查询
我们已经知道如何对数据进行过滤和排序。 当然,通常我们需要同时进行过滤和排序查询的操作。 因此,你可以简单地写成这种“链式”的形式:
- >>> Publisher.objects.filter(country="U.S.A.").order_by("-name")
- [<Publisher: O'Reilly>, <Publisher: Apress>]
你应该没猜错,转换成SQL查询就是 WHERE 和 ORDER BY 的组合:
- SELECT id, name, address, city, state_province, country, website
- FROM books_publisher
- WHERE country = 'U.S.A'
- ORDER BY name DESC;
关联查询
现在你找到了一本书的对象b1, 书与作者已经进行多对多关联,此时你想知道书的作者是谁?
删除
删除b1这本书,看下图,删除b1时会把书与作者中间表对应内容也删除,真牛!!
参考博客: http://www.cnblogs.com/alex3714/articles/5457672.html 大王这篇博客写得太乱了……
写好久,脖子酸
转发注明出处: http://www.cnblogs.com/0zcl/p/6562380.html
django进阶-1的更多相关文章
- Python之路,Day16 - Django 进阶
Python之路,Day16 - Django 进阶 本节内容 自定义template tags 中间件 CRSF 权限管理 分页 Django分页 https://docs.djangoproj ...
- django进阶补充
前言: 这篇博客对上篇博客django进阶作下补充. 一.效果图 前端界面较简单(丑),有两个功能: 从数据库中取出书名 eg: 新书A 在form表单输入书名,选择出版社,选择作者(多选),输入完毕 ...
- django进阶-3
先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...
- django进阶-4
前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...
- Django进阶篇【1】
注:本篇是Django进阶篇章,适合人群:有Django基础,关于Django基础篇,将在下一章节中补充! 首先我们一起了解下Django整个请求生命周期: Django 请求流程,生命周期: 路由部 ...
- Django进阶知识
drf学习之Django进阶点 一.Django migrations原理 1.makemigrattions: 相当于在每个app下的migrations文件夹下生成一个py脚本文件用于创建表或则修 ...
- django进阶-查询(适合GET4以上人群阅读)
前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...
- django进阶-modelform&admin action
先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...
- django进阶-小实例
前言: 这篇博客对上篇博客django进阶作下补充. 一.效果图 前端界面较简单(丑),有两个功能: 从数据库中取出书名 eg: 新书A 在form表单输入书名,选择出版社,选择作者(多选),输入完毕 ...
随机推荐
- unity---Courtine 协程
尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 记得去年6月份刚开始实习的时候,当时要我写网络层的结构,用到了协程,当时有点懵,完全不知道Unity协程的执行机制是 ...
- Linux Shell nohup命令用法
linux的nohup命令的用法. 在应用Unix/Linux时,我们一般想让某个程序在后台运行,于是我们将常会用 & 在程序结尾来让程序自动运行.比如我们要运行mysql在后台: /us ...
- 制作移动端手机网站过程中的SEO优化方法技巧
据国内三大运营商数据来看,中国的手机用户数已达10亿,超过2/5的移动用户每个月都会从手机终端访问网页,如今的移动端手机网站比例肯定有提升,但是对于这些存在的移动版本网站来说,马海祥查看了很大一部分手 ...
- 【Access-Control-Allow-Origin】跨域问题
[前言] 在实际项目中,可能是多个项目共同完成某个功能,他们之间需要实现数据的交互.这样就会需要有跨域的问题. 比如,发布在不同电脑上的不同项目之间,用不同语言开发的项目之间…… [JSONP] 当使 ...
- glsl boom
原理: 1.渲染场景到fbo 2.对fbo进行高斯横向,纵向模糊,到新的fbo 3.对两张图进行叠加 模糊后的 效果就这样 给数据加大 <-vertex-> #version varyin ...
- 环境变量PATH/cp命令/mv命令/文档查看cat/more/less/head/tail
2.10 环境变量PATH 2.11 cp命令 2.12 mv命令 2.13 文档查看cat/more/less/head/tail which rmdir 可以查到命令的路径 例如: ls 命令是 ...
- uva 548 Tree(通过后序,先序重建树+dfs)
难点就是重建树,指针參数的传递今天又看了看.应该是曾经没全然弄懂.昨天真没效率,还是不太专心啊.以后一定得慢慢看.不能急躁,保持寻常心,. 分析: 通过兴许序列和中序序列重建树,用到了结构体指针.以及 ...
- HOStringSense大段字符串检测器
下载地址:https://github.com/holtwick/HOStringSense-for-Xcode 修改HOStringSense.xcodeproj工程里的HOStringHelper ...
- asp.net mvc maproute定义可变数量的自定义片断变量
有时候我们定义了如{controller}/{action}/{id}之类的路由规则,但是后面还可能跟上一堆可能会有可能不会有,但是路由规则是一样的,如{controller}/{action}/{i ...
- 11 go并发编程-上
其他编程语言并发编程的效果 并发编程可以让开发者实现并行的算法以及编写充分利用多核处理器和多核性能的程序.在当前大部分主流的编程语言里,如C,C++,java等,编写维护和调试并发程序相比单线程程序而 ...