Django基础

3     在django的品类中会默认使用sqlite数据库,在settings里有如下设置:

       图片 1    

假诺我们想要更改数据库,需要修改如下:

        图片 2 

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.mysql', 

        'NAME': 'books',    #你的数据库名称

        'USER': 'root',   #你的数据库用户名

        'PASSWORD': '', #你的数据库密码

        'HOST': '', #你的数据库主机,留空默认为localhost

        'PORT': '3306', #你的数据库端口

    }

}

注意:

图片 3图片 4

复制代码
NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建

USER和PASSWORD分别是数据库的用户名和密码。

设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。

然后,启动项目,会报错:no module named MySQLdb

这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb对于py3有很大问题,所以我们需要的驱动是PyMySQL

所以,我们只需要找到项目名文件下的__init__,在里面写入:

import pymysql
pymysql.install_as_MySQLdb()

问题解决!

View Code

 

5.2  ORM表模型

{% if %} 的使用 

{% if
%}标签总结一个变量值,如假如“true”,即它存在、不为空并且不是false的boolean值,系统则会呈现{%
if %}和{% endif %}间的有所内容

图片 5

{% if num >= 100 and 8 %}

    {% if num > 200 %}
        <p>num大于200</p>
    {% else %}
        <p>num大于100小于200</p>
    {% endif %}

{% elif num < 100%}
    <p>num小于100</p>

{% else %}
    <p>num等于100</p>

{% endif %}



{% if %} 标签接受and,or或者not来测试多个变量值或者否定一个给定的变量
{% if %} 标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义,例如下面的标签是不合法的:

{% if obj1 and obj2 or obj3 %} 

图片 6

2    mysql驱动程序

  •    MySQLdb(mysql python)
  •    mysqlclient
  •    MySQL
  •    PyMySQL(纯python的mysql驱动程序)

ORM之删(delete)

>>> Book.objects.filter(id=1).delete()
(3, {'app01.Book_authors': 2, 'app01.Book': 1})

大家外表上剔除了一条消息,实际却删除了三条,因为我们删除的这本书在Book_authors表中有两条有关音讯,这种删除格局就是django默认的级联删除。

2.1.3 URLconf 在怎么上寻找

URLconf 在呼吁的URL 上搜索,将它看做一个常见的Python
字符串。不包括GET和POST参数以及域名。

例如,http://www.example.com/myapp/ 请求中,URLconf 将查找myapp/

http://www.example.com/myapp/?page=3 请求中,URLconf
仍将追寻myapp/

URLconf 不检查请求的法门。换句话讲,所有的伸手方法 ——
同一个URL的POSTGETHEAD等等 —— 都将路由到同样的函数。

一 什么是web框架?

框架,即framework,特指为釜底抽薪一个开放性问题而规划的保有自然约束性的辅助结构,使用框架可以帮您快速支付特定的连串,简单地说,就是你用外人搭建好的戏台来做表演。

对于具有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

图片 7图片 8

import socket

def handle_request(client):

    buf = client.recv(1024)
    client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf8"))
    client.send("<h1 style='color:red'>Hello, yuan</h1>".encode("utf8"))

def main():

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost',8001))
    sock.listen(5)

    while True:
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()

if __name__ == '__main__':

    main()

View Code

 

最简便的Web应用就是先把HTML用文件保留好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,再次来到。

比方要动态生成HTML,就需要把上述手续自己来贯彻。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是搬运工活,如若我们温馨来写这个底层代码,还没开端写动态HTML呢,就得花个把月去读HTTP规范。

     
正确的做法是底层代码由特其余服务器软件实现,我们用Python专注于生成HTML文档。因为大家不指望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个联结的接口,让大家专心用Python编写Web业务。

这一个接口就是WSGI:Web Server Gateway Interface。

—————————–Do a web  framework
ourselves
—————————**

{% load %}

{% for %}的使用

{% for
%}标签允许你按顺序遍历一个队列中的各类要素,每一遍循环模板系统都会渲染{%
for %}和{% endfor %}之间的具备内容

图片 9

<ul>
{% for obj in list %}
    <li>{{ obj.name }}</li>
{% endfor %}
</ul>


#在标签里添加reversed来反序循环列表:

    {% for obj in list reversed %}
    ...
    {% endfor %}

#{% for %}标签可以嵌套:

    {% for country in countries %}
        <h1>{{ country.name }}</h1>
        <ul>
         {% for city in country.city_list %}
            <li>{{ city }}</li>
         {% endfor %}
        </ul>
    {% endfor %}


#系统不支持中断循环,系统也不支持continue语句,{% for %}标签内置了一个forloop模板变量,
#这个变量含有一些属性可以提供给你一些关于循环的信息

1,forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1:

    {% for item in todo_list %}
        <p>{{ forloop.counter }}: {{ item }}</p>
    {% endfor %}
2,forloop.counter0 类似于forloop.counter,但它是从0开始计数,第一次循环设为0
3,forloop.revcounter
4,forloop.revcounter0
5,forloop.first当第一次循环时值为True,在特别情况下很有用:


    {% for object in objects %}   
         {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}   
         {{ object }}   
        </li>  
    {% endfor %}  

# 富有魔力的forloop变量只能在循环中得到,当模板解析器到达{% endfor %}时forloop就消失了
# 如果你的模板context已经包含一个叫forloop的变量,Django会用{% for %}标签替代它
# Django会在for标签的块中覆盖你定义的forloop变量的值
# 在其他非循环的地方,你的forloop变量仍然可用


#{% empty %}

{{li }}
      {%  for i in li %}
          <li>{{ forloop.counter0 }}----{{ i }}</li>
      {% empty %}
          <li>this is empty!</li>
      {% endfor %}

#         [11, 22, 33, 44, 55]
#            0----11
#            1----22
#            2----33
#            3----44
#            4----55

图片 10

QuerySet与惰性机制

所谓惰性机制:Publisher.objects.all()或者.filter()等都只是回到了一个QuerySet(查询结果集对象),它并不会即刻执行sql,而是当调用QuerySet的时候才实施。

QuerySet特点:

       <1>  可迭代的

       <2>  可切片

图片 11

    #objs=models.Book.objects.all()#[obj1,obj2,ob3...]

    #QuerySet:   可迭代

    # for obj in objs:#每一obj就是一个行对象
    #     print("obj:",obj)
    # QuerySet:  可切片

    # print(objs[1])
    # print(objs[1:4])
    # print(objs[::-1])

图片 12

QuerySet的飞跃使用:

图片 13图片 14

<1>Django的queryset是惰性的

     Django的queryset对应于数据库的若干记录(row),通过可选的查询来过滤。例如,下面的代码会得
     到数据库中名字为‘Dave’的所有的人:person_set = Person.objects.filter(first_name="Dave")
     上面的代码并没有运行任何的数据库查询。你可以使用person_set,给它加上一些过滤条件,或者将它传给某个函数,
     这些操作都不会发送给数据库。这是对的,因为数据库查询是显著影响web应用性能的因素之一。

<2>要真正从数据库获得数据,你可以遍历queryset或者使用if queryset,总之你用到数据时就会执行sql.
   为了验证这些,需要在settings里加入 LOGGING(验证方式)
        obj=models.Book.objects.filter(id=3)
        # for i in obj:
        #     print(i)

        # if obj:
        #     print("ok")

<3>queryset是具有cache的
     当你遍历queryset时,所有匹配的记录会从数据库获取,然后转换成Django的model。这被称为执行
    (evaluation).这些model会保存在queryset内置的cache中,这样如果你再次遍历这个queryset,
     你不需要重复运行通用的查询。
        obj=models.Book.objects.filter(id=3)

        # for i in obj:
        #     print(i)
                          ## models.Book.objects.filter(id=3).update(title="GO")
                          ## obj_new=models.Book.objects.filter(id=3)
        # for i in obj:
        #     print(i)   #LOGGING只会打印一次

<4>
     简单的使用if语句进行判断也会完全执行整个queryset并且把数据放入cache,虽然你并不需要这些
     数据!为了避免这个,可以用exists()方法来检查是否有数据:

            obj = Book.objects.filter(id=4)
            #  exists()的检查可以避免数据放入queryset的cache。
            if obj.exists():
                print("hello world!")

<5>当queryset非常巨大时,cache会成为问题

     处理成千上万的记录时,将它们一次装入内存是很浪费的。更糟糕的是,巨大的queryset可能会锁住系统
     进程,让你的程序濒临崩溃。要避免在遍历数据的同时产生queryset cache,可以使用iterator()方法
     来获取数据,处理完数据就将其丢弃。
        objs = Book.objects.all().iterator()
        # iterator()可以一次只从数据库获取少量数据,这样可以节省内存
        for obj in objs:
            print(obj.name)
        #BUT,再次遍历没有打印,因为迭代器已经在上一次遍历(next)到最后一次了,没得遍历了
        for obj in objs:
            print(obj.name)

     #当然,使用iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。所以使
     #用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询

总结:
    queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库。
使用exists()和iterator()方法可以优化程序对内存的使用。不过,由于它们并不会生成queryset cache,可能
会造成额外的数据库查询。

View Code

对象查询,单表条件查询,多表口径关联查询

图片 15

#--------------------对象形式的查找--------------------------
    # 正向查找
    ret1=models.Book.objects.first()
    print(ret1.title)
    print(ret1.price)
    print(ret1.publisher)
    print(ret1.publisher.name)  #因为一对多的关系所以ret1.publisher是一个对象,而不是一个queryset集合

    # 反向查找
    ret2=models.Publish.objects.last()
    print(ret2.name)
    print(ret2.city)
    #如何拿到与它绑定的Book对象呢?
    print(ret2.book_set.all()) #ret2.book_set是一个queryset集合

#---------------了不起的双下划线(__)之单表条件查询----------------

#    models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
#
#    models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
#    models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
#
#    models.Tb1.objects.filter(name__contains="ven")
#    models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
#
#    models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and
#
#    startswith,istartswith, endswith, iendswith,

#----------------了不起的双下划线(__)之多表条件关联查询---------------

# 正向查找(条件)

#     ret3=models.Book.objects.filter(title='Python').values('id')
#     print(ret3)#[{'id': 1}]

      #正向查找(条件)之一对多

      ret4=models.Book.objects.filter(title='Python').values('publisher__city')
      print(ret4)  #[{'publisher__city': '北京'}]

      #正向查找(条件)之多对多
      ret5=models.Book.objects.filter(title='Python').values('author__name')
      print(ret5)
      ret6=models.Book.objects.filter(author__name="alex").values('title')
      print(ret6)

      #注意
      #正向查找的publisher__city或者author__name中的publisher,author是book表中绑定的字段
      #一对多和多对多在这里用法没区别

# 反向查找(条件)

    #反向查找之一对多:
    ret8=models.Publisher.objects.filter(book__title='Python').values('name')
    print(ret8)#[{'name': '人大出版社'}]  注意,book__title中的book就是Publisher的关联表名

    ret9=models.Publisher.objects.filter(book__title='Python').values('book__authors')
    print(ret9)#[{'book__authors': 1}, {'book__authors': 2}]

    #反向查找之多对多:
    ret10=models.Author.objects.filter(book__title='Python').values('name')
    print(ret10)#[{'name': 'alex'}, {'name': 'alvin'}]

    #注意
    #正向查找的book__title中的book是表名Book
    #一对多和多对多在这里用法没区别

图片 16

注意:条件查询即与目的查询相应,是指在filter,values等格局中的通过__来家喻户晓询问条件。

{% with %}

用更简约的变量名替代复杂的变量名

{% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}

2.1.5 指定视图参数的默认值

有一个惠及的小技巧是指定视图参数的默认值。 上边是一个URLconf
和视图的言传身教:

图片 17

# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# View (in blog/views.py)
def page(request, num="1"):

    ...

图片 18

在地方的例证中,六个URL模式指向同一个视图views.page ——
不过第一个格局不会从URL
中抓获任何值。要是第一个情势匹配,page() 函数将接纳num参数的默认值”1″。假设第二个情势匹配,page() 将利用正则表明式捕获的num 值。

3.2  飞快函数

表(模型)的创建:

实例:我们来倘使下边这么些概念,字段和关联

笔者模型:一个作者有姓名。

笔者详细模型:把笔者的详情放到详情表,包含性别,email地址和出生日期,作者详情模型和作者模型之间是一定的涉及(one-to-one)(类似于每个人和他的身份证之间的关系),在大部情景下我们并未必要将她们拆分成两张表,这里只是引出一对一的定义。

出版商模型:出版商出名称,地址,所在城市,省,国家和网站。

书本模型:书籍有书名和出版日期,一本书可能会有三个作者,一个作者也可以写多本书,所以作者和本本的涉嫌就是多对多的涉及关系(many-to-many),一本书只应该由一个出版商出版,所以出版商和书本是一对多涉及关系(one-to-many),也被称作外键。

图片 19图片 20

from django.db import models<br>
class Publisher(models.Model):
    name = models.CharField(max_length=30, verbose_name="名称")
    address = models.CharField("地址", max_length=50)
    city = models.CharField('城市',max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()

    class Meta:
        verbose_name = '出版商'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=30)
    def __str__(self):
        return self.name

class AuthorDetail(models.Model):
    sex = models.BooleanField(max_length=1, choices=((0, '男'),(1, '女'),))
    email = models.EmailField()
    address = models.CharField(max_length=50)
    birthday = models.DateField()
    author = models.OneToOneField(Author)

class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2,default=10)
    def __str__(self):
        return self.title

View Code

分析代码:

       <1> 
每个数据模型都是django.db.models.Model的子类,它的父类Model包含了颇具必要的和数据库交互的法门。并提供了一个简介赏心悦目的概念数据库字段的语法。

       <2> 
每个模型相当于单个数据库表(多对多关系不同,会多生成一张关系表),每个属性也是以此表中的字段。属性名就是字段名,它的连串(例如Char菲尔德(Field)(Field))相当于数据库的字段类型(例如varchar)。我们可以小心下任何的品类都和数据库里的怎么字段对应。

       <3>  模型之间的两种关系:一对一,一对多,多对多。

             一对一:实质就是在主外键(author_id就是foreign
key)的涉嫌基础上,给外键加了一个UNIQUE=True的特性;

             一对多:就是主外键关系;(foreign key)

             多对多:(ManyToMany菲尔德(Field)(Field))
自动创造第三张表(当然大家也得以团结创办第三张表:三个foreign key)

2.3 name参数

图片 21图片 22

urlpatterns = [
    url(r'^index',views.index,name='INDEX'),

]
###################

def index(req):
    if req.method=='POST':
        username=req.POST.get('username')
        password=req.POST.get('password')
        if username=='alex' and password=='123':
            return HttpResponse("登陆成功")

    return render(req,'index.html')

#####################

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#     <form action="/index/" method="post">#}
     <form action="{% url 'INDEX' %}" method="post">
         用户名:<input type="text" name="username">
         密码:<input type="password" name="password">
         <input type="submit" value="submit">
     </form>
</body>
</html>


#######################

'''
复制代码

View Code

 

三 编写视图

一个视图函数,或者简而言之叫做视图,是一个简练的Python函数,它接受web请求,并且重回web响应。响应得以是一张网页的HTML内容,一个重定向,一个404荒谬,一个XML文档,或者一张图片.
. .
是此外东西都足以。无论视图本身带有咋样逻辑,都要回去响应。代码写在哪儿也不在乎,只要它在你的Python目录下边。除此之外没有更多的渴求了——可以说“没有怎么神奇的地方”。为了可以把代码放在某个地点,惯例是把视图放在叫做views.py的文本中,然后把它放到你的门类依然采用目录里。

一  认识ModelAdmin

   管理界面的定制类,如需扩充特定的model界面需从该类继承。

ORM之查(filter,value) 

step 1:

图片 23图片 24

from wsgiref.simple_server import make_server


def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, web!</h1>']


httpd = make_server('', 8080, application)

print('Serving HTTP on port 8000...')
# 开始监听HTTP请求:
httpd.serve_forever()

View Code

注意:

图片 25图片 26

整个application()函数本身没有涉及到任何解析HTTP的部分,也就是说,底层代码不需要我们自己编写,
我们只负责在更高层次上考虑如何响应请求就可以了。

application()函数必须由WSGI服务器来调用。有很多符合WSGI规范的服务器,我们可以挑选一个来用。

Python内置了一个WSGI服务器,这个模块叫wsgiref    


application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:

        //environ:一个包含所有HTTP请求信息的dict对象;

        //start_response:一个发送HTTP响应的函数。

在application()函数中,调用:

start_response('200 OK', [('Content-Type', 'text/html')])

就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。
start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每
个Header用一个包含两个str的tuple表示。

通常情况下,都应该把Content-Type头发送给浏览器。其他很多常用的HTTP Header也应该发送。

然后,函数的返回值b'<h1>Hello, web!</h1>'将作为HTTP响应的Body发送给浏览器。

有了WSGI,我们关心的就是如何从environ这个dict对象拿到HTTP请求信息,然后构造HTML,
通过start_response()发送Header,最后返回Body。

View Code

step 2

图片 27图片 28

print(environ['PATH_INFO'])
    path=environ['PATH_INFO']
    start_response('200 OK', [('Content-Type', 'text/html')])
    f1=open("index1.html","rb")
    data1=f1.read()
    f2=open("index2.html","rb")
    data2=f2.read()

    if path=="/yuan":
        return [data1]
    elif path=="/alex":
        return [data2]
    else:
        return ["<h1>404</h1>".encode('utf8')]

View Code

step3

图片 29图片 30

from wsgiref.simple_server import make_server

def f1():
    f1=open("index1.html","rb")
    data1=f1.read()
    return [data1]

def f2():
    f2=open("index2.html","rb")
    data2=f2.read()
    return [data2]

def application(environ, start_response):

    print(environ['PATH_INFO'])
    path=environ['PATH_INFO']
    start_response('200 OK', [('Content-Type', 'text/html')])


    if path=="/yuan":
        return f1()

    elif path=="/alex":
        return f2()

    else:
        return ["<h1>404</h1>".encode("utf8")]


httpd = make_server('', 8502, application)

print('Serving HTTP on port 8084...')

# 开始监听HTTP请求:
httpd.serve_forever()

View Code

step4

图片 31图片 32

from wsgiref.simple_server import make_server


def f1(req):
    print(req)
    print(req["QUERY_STRING"])

    f1=open("index1.html","rb")
    data1=f1.read()
    return [data1]

def f2(req):

    f2=open("index2.html","rb")
    data2=f2.read()
    return [data2]

import time

def f3(req):        #模版以及数据库

    f3=open("index3.html","rb")
    data3=f3.read()
    times=time.strftime("%Y-%m-%d %X", time.localtime())
    data3=str(data3,"utf8").replace("!time!",str(times))


    return [data3.encode("utf8")]


def routers():

    urlpatterns = (
        ('/yuan',f1),
        ('/alex',f2),
        ("/cur_time",f3)
    )
    return urlpatterns


def application(environ, start_response):

    print(environ['PATH_INFO'])
    path=environ['PATH_INFO']
    start_response('200 OK', [('Content-Type', 'text/html')])


    urlpatterns = routers()
    func = None
    for item in urlpatterns:
        if item[0] == path:
            func = item[1]
            break
    if func:
        return func(environ)
    else:
        return ["<h1>404</h1>".encode("utf8")]

httpd = make_server('', 8518, application)

print('Serving HTTP on port 8084...')

# 开始监听HTTP请求:

httpd.serve_forever()

View Code

同路人们,不知不觉我们温馨曾经写出一个web框架啦!

3.1 一个简练的视图

下面是一个重临当前些天期和时间作为HTML文档的视图:

图片 33

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

图片 34

让我们逐行阅读方面的代码:

  • 第一,大家从
    django.http模块导入了HttpResponse类,以及Python的datetime库。
  • 紧接着,大家定义了current_datetime函数。它是一个视图函数。每个视图函数都应收取HttpRequest对象作为第一个参数,一般叫做request。
  • 小心视图函数的名目并不首要;不需要用一个联结的命名形式来定名,以便让Django识别它。大家将其命名为current_datetime,是因为这么些称呼可以准确地反映出它的效果。
  • 本条视图会再次回到一个HttpResponse对象,其中含有生成的响应。每个视图函数都要赶回HttpResponse对象

'''
http请求-响应过程中有两个核心对象:

        http请求对象:HttpRequest

        http响应响应:HttpResponse

所在位置:django.http

'''

extend模板继承

到目前停止,大家的模版范例都只是些零星的 HTML
片段,但在其实使用中,你将用 Django 模板系统来创制整个 HTML 页面。
这就牵动一个宽广的 Web 开发问题:
在所有网站中,怎么着缩短共用页面区域(比如站点导航)所引起的再一次和冗余代码?Django
解决此类题材的首选办法是接纳一种优雅的方针—— 模板继承 。

精神上来说,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所蕴藏站点公用部分和定义块举行重载。

让我们通过修改 current_datetime.html 文件,为 current_datetime 创立一个更为完整的模板来回味一下这种做法:

图片 35

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>The current time</title>
</head>
<body>
    <h1>My helpful timestamp site</h1>
    <p>It is now {{ current_date }}.</p>

    <hr>
    <p>Thanks for visiting my site.</p>
</body>
</html>

图片 36

那看起来很棒,但假若我们要为 hours_ahead 视图制造另一个模板会生出什么样事情啊?

图片 37

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>Future time</title>
</head>
<body>
    <h1>My helpful timestamp site</h1>
    <p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>

    <hr>
    <p>Thanks for visiting my site.</p>
</body>
</html> 

图片 38

Django 的沙盘继承系统解决了这一个问题。 你可以将其就是服务器端 include
的逆向思维版本。
你可以对这些不同 的代码段举办定义,而不是 共同 代码段。

首先步是定义 基础模板,该框架之后将由子模板所继承。
以下是我们脚下所讲述范例的底子模板:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <h1>My helpful timestamp site</h1>
    {% block content %}{% endblock %}
    {% block footer %}
    <hr>
    <p>Thanks for visiting my site.</p>
    {% endblock %}
</body>
</html>

这个叫做 base.html 的沙盘定义了一个简单的 HTML
框架文档,我们将在本站点的富有页面中行使。
子模板的法力就是重载、添加或保留这些块的情节。
(尽管您一直按顺序学习到这里,保存那些文件到您的template目录下,命名为 base.html .)

咱俩选拔模板标签: {% block %} 。
所有的 {% block %} 标签告诉模板引擎,子模板可以重载那些有些。
每个{% block %}标签所要做的是告诉模板引擎,该模板下的这一块内容将有可能被子模板覆盖。

近来我们早就有了一个主导模板,我们可以修改 current_datetime.html 模板来
使用它:

图片 39

{% extends "base.html" %}

{% block title %}The current time{% endblock %}

{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}

图片 40

再为 hours_ahead 视图创制一个模板,看起来是如此的:

图片 41

{% extends "base.html" %}

{% block title %}Future time{% endblock %}

{% block content %}
<p>In {{ hour_offset }} hour(s), it will be {{ next_time }}.</p>
{% endblock %}

图片 42

看起来很赏心悦目是不是? 每个模板只含有对友好而言 绝世 的代码。
无需多余的一部分。
假如想拓展站点级的计划修改,仅需修改 base.html ,所有其他模板会登时反映出所作修改。

以下是其工作方法:

     
在加载 current_datetime.html 模板时,模板引擎发现了 {% extends %} 标签,
注意到该模板是一个子模板。
模板引擎登服饰载其父模板,即本例中的 base.html 。此时,模板引擎注意到 base.html 中的多少个 {% block %} 标签,并用子模板的内容替换这多少个block
。因而,引擎将会拔取大家在 { block title %} 中定义的标题,对 {% block content %} 也是如此。
所以,网页标题一块将由{% block title %}轮换,同样地,网页的情节一块将由 {% block content %}替换。

    
注意由于子模板并没有定义 footer 块,模板系统将动用在父模板中定义的值。
父模板 {% block %} 标签中的内容总是被看做一条退路。继承并不会影响到模板的上下文。
换句话说,任何处在继承树上的模板都可以访问到您传到模板中的每一个模板变量。你可以按照需要采用任意多的接续次数。
使用持续的一种常见形式是上边的三层法:

   <1> 创建 base.html 模板,在其中定义站点的主要外观感受。 这些都是不常修改甚至从不修改的部分。
   <2> 为网站的每个区域创建 base_SECTION.html 模板(例如, base_photos.html 和 base_forum.html )。这些模板对base.html 进行拓展,
       并包含区域特定的风格与设计。
   <3> 为每种类型的页面创建独立的模板,例如论坛页面或者图片库。 这些模板拓展相应的区域模板。

以此模式可最大限度地选拔代码,并使得向公共区域(如区域级的领航)添加始末成为一件轻松的做事。

以下是采纳模板继承的片段门路:

图片 43

 <1>如果在模板中使用 {% extends %} ,必须保证其为模板中的第一个模板标记。 否则,模板继承将不起作用。

 <2>一般来说,基础模板中的 {% block %} 标签越多越好。 记住,子模板不必定义父模板中所有的代码块,因此
    你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。 俗话说,钩子越
    多越好。

 <3>如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个 {% block %} 中。
    如果你需要访问父模板中的块的内容,使用 {{ block.super }}这个标签吧,这一个魔法变量将会表现出父模
    板中的内容。 如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。

 <4>不允许在同一个模板中定义多个同名的 {% block %} 。 存在这样的限制是因为block 标签的工作方式是双向的。
    也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个
    相同名称的 {% block %} 标签,父模板将无从得知要使用哪个块的内容。

图片 44

五 数据库与ORM

二 MVC和MTV模式

Django的M电视机形式本质是各组件之间为了保持松耦合关系,Django的M电视机分别代表:

       Model(模型):负责作业对象与数据库的对象(ORM)

       Template(模版):负责什么把页面彰显给用户

       View(视图):负责作业逻辑,并在合适的时候调用Model和Template

     
 其它,Django还有一个url分发器,它的效能是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

图片 45

回来顶部

Django基本命令

1、成立一个django project

1
django-admin.py startproject mysite

 当前目录下会生成mysite的工程,目录结构如下:

        图片 46

  • manage.py —– Django项目里面的工具,通过它可以调用django shell和数据库等。
  • settings.py —- 包含了品种的默认设置,包括数据库音讯,调试标志以及另外部分行事的变量。
  • urls.py —– 负责把URL情势映射到应用程序。

2、在mysite目录下创办应用,比如blog:

1
python manage.py startapp blog

        图片 47

3、启动django项目

1
python manage.py runserver 8080

     
 这样大家的django就开行起来了!当我们访问:http://127.0.0.1:8080/时就可以看到:

       图片 48

4、同步转移数据库表或字段

图片 49

'''
    python manage.py syncdb

    注意:Django 1.7.1 及以上的版本需要用以下命令
    python manage.py makemigrations
    python manage.py migrate

'''

图片 50

那种措施可以创制表,当您在models.py中新增了类时,运行它就可以活动在数据库中开创表了,不用手动创制。

5、清空数据库

1
python manage.py flush

 此命令会了然是 yes 仍然 no, 拔取 yes
会把数据总体清空掉,只留下空表。

6、成立一级管理员

图片 51

'''
    python manage.py createsuperuser

    # 按照提示输入用户名和对应的密码就好了邮箱可以留空,用户名和密码必填

    # 修改 用户密码可以用:
    python manage.py changepassword username

'''

图片 52

7、Django 项目条件终端

1
python manage.py shell

其一命令和 直接运行 python 进入 shell 的分别是:你可以在那几个 shell
里面调用当前项目标 models.py 中的 API,对于操作数据的测试非凡便于。

8、Django 项目环境终端

ython manage.py dbshell

Django 会自动进入在settings.py中设置的数据库,倘使是 MySQL 或
postgreSQL,会要求输入数据库用户密码。

在这些终端可以举行数据库的SQL语句。假设您对SQL比较熟练,可能喜欢这种艺术。

9、更多命令

1
python manage.py

 查看所有的通令,忘记子名称的时候特别有用。

10 static配置

#3、STATIC文件还可以配置STATICFILES_DIRS,指定额外的静态文件存储位置。
    #  STATIC_URL的含义与MEDIA_URL类似。

    # ----------------------------------------------------------------------------
    #注意1:
        #为了后端的更改不会影响前端的引入,避免造成前端大量修改

        STATIC_URL = '/static/'               #引用名
        STATICFILES_DIRS = (
            os.path.join(BASE_DIR,"statics")  #实际名 ,即实际文件夹的名字
        )

        #django对引用名和实际名进行映射,引用时,只能按照引用名来,不能按实际名去找
        #<script src="/statics/jquery-3.1.1.js"></script>
        #------error-----不能直接用,必须用STATIC_URL = '/static/':
        #<script src="/static/jquery-3.1.1.js"></script>

    #注意2(statics文件夹写在不同的app下,静态文件的调用):

        STATIC_URL = '/static/'

        STATICFILES_DIRS=(
            ('hello',os.path.join(BASE_DIR,"app01","statics")) ,
        )

        #<script src="/static/hello/jquery-1.8.2.min.js"></script>

    #注意3:
        STATIC_URL = '/static/'
        {% load staticfiles %}
       # <script src={% static "jquery-1.8.2.min.js" %}></script>


路由安排体系(URLconf)

URL配置(URLconf)就像Django
所支撑网站的目录。它的本来面目是URL与要为该URL调用的视图函数之间的映射表;你就是以这种情势告知Django,对于这么些URL调用这段代码,对于那么些URL调用这段代码。

    '''

    urlpatterns = [
         url(正则表达式, views视图函数,参数,别名),
]


参数说明:

    一个正则表达式字符串
    一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
    可选的要传递给视图函数的默认参数(字典形式)
    一个可选的name参数

    '''

ORM之改(update和save)

实例:

    图片 53

注意:

<1>
第三种方法修改不可能用get的缘由是:update是QuerySet对象的章程,get再次来到的是一个model对象,它从未update方法,而filter重回的是一个QuerySet对象(filter里面的规则可能有六个标准适合,比如name=’alvin’,可能有两个name=’alvin’的行数据)。

<2>在“插入和更新数据”小节中,我们有提到模型的save()方法,这个方法会更新一行里的所有列。 而某些情况下,我们只需要更新行里的某几列。

图片 54 View Code

此外,update()方法对于其他结果集(QuerySet)均有效,这表示你可以而且革新多条记录update()方法会再次来到一个整型数值,表示受影响的记录条数。

只顾,这里因为update再次回到的是一个整形,所以没法用query属性;对于每回创立一个目的,想显示相应的raw
sql,需要在settings加上日志记录部分:

图片 55 View Code

2.1 URLconf的正则字符串参数

{% url %}

引用路由配置的地址

<form action="{% url "bieming"%}" >
          <input type="text">
          <input type="submit"value="提交">
          {%csrf_token%}
</form>

1    django默认扶助sqlite,mysql, oracle,postgresql数据库。

     <1> sqlite

            django默认使用sqlite的数据库,默认自带sqlite的数据库驱动 ,
引擎名称:django.db.backends.sqlite3

     <2> mysql

            引擎名称:django.db.backends.mysql

4.2.3 变量的过滤器(filter)的行使

语法格式:      {{obj|filter:param}}

图片 56图片 57

复制代码
 # 1  add          :   给变量加上相应的值
   #
   # 2  addslashes   :    给变量中的引号前加上斜线
   #
   # 3  capfirst     :    首字母大写
   #
   # 4  cut          :   从字符串中移除指定的字符
   #
   # 5  date         :   格式化日期字符串
   #
   # 6  default      :   如果值是False,就替换成设置的默认值,否则就是用本来的值
   #
   # 7  default_if_none:  如果值是None,就替换成设置的默认值,否则就使用本来的值


#实例:

#value1="aBcDe"
{{ value1|upper }}<br>

#value2=5
{{ value2|add:3 }}<br>

#value3='he  llo wo r ld'
{{ value3|cut:' ' }}<br>

#import datetime
#value4=datetime.datetime.now()
{{ value4|date:'Y-m-d' }}<br>

#value5=[]
{{ value5|default:'空的' }}<br>

#value6='<a href="#">跳转</a>'

{{ value6 }}

{% autoescape off %}
  {{ value6 }}
{% endautoescape %}

{{ value6|safe }}<br>

{{ value6|striptags }}

#value7='1234'
{{ value7|filesizeformat }}<br>
{{ value7|first }}<br>
{{ value7|length }}<br>
{{ value7|slice:":-1" }}<br>

#value8='http://www.baidu.com/?a=1&b=3'
{{ value8|urlencode }}<br>
    value9='hello I am yuan'

View Code

4.2.4 标签(tag)的使用(使用大括号和比重的结缘来代表使用tag)

语法格式:    {% tags %}

查询API:

图片 58

# 查询相关API:

#  <1>filter(**kwargs):      它包含了与所给筛选条件相匹配的对象

#  <2>all():                 查询所有结果

#  <3>get(**kwargs):         返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。

#-----------下面的方法都是对查询的结果再进行处理:比如 objects.filter.values()--------

#  <4>values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列 model的实例化对象,而是一个可迭代的字典序列

#  <5>exclude(**kwargs):     它包含了与所给筛选条件不匹配的对象

#  <6>order_by(*field):      对查询结果排序

#  <7>reverse():             对查询结果反向排序

#  <8>distinct():            从返回结果中剔除重复纪录

#  <9>values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列

#  <10>count():              返回数据库中匹配查询(QuerySet)的对象数量。

#  <11>first():               返回第一条记录

#  <12>last():                返回最后一条记录

#  <13>exists():             如果QuerySet包含数据,就返回True,否则返回False

图片 59

图片 60 View Code

2.1.2 闻明分组(named group)

地点的言传身教使用简单的、没有命名的正则表明式组(通过圆括号)来捕获URL
中的值并以地点参数传递给视图。在更高级的用法中,可以应用命名的正则表明式组来捕获URL
中的值并以关键字 参数传递给视图。

在Python
正则表明式中,命名正则表明式组的语法是(?P<name>pattern),其中name 是组的名号,pattern 是要配合的格局。

下边是上述URLconf 使用命名组的重写:

图片 61

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),
]

图片 62

本条实现与前方的示范完全相同,只有一个轻微的歧异:捕获的值作为重中之重字参数而不是岗位参数传递给视图函数。例如:

    /articles/2005/03/    
    请求将调用views.month_archive(request, year='2005', month='03')函数
    /articles/2003/03/03/ 
    请求将调用函数views.article_detail(request, year='2003', month='03', day='03')。

在实际应用中,这意味着你的URLconf 会更加分明且不便于发生参数顺序问题的错误
——
你可以在你的视图函数定义中重新安排参数的一一。当然,这多少个便宜是以简洁为代价;有些开发人士认为命名组语法丑陋而麻烦。

 

 知识预览

  • Django基本命令
  • 二 路由安排连串(URLconf)
  • 三 编写视图
  • 四 Template
  • 五 数据库与ORM
  • admin的配置

F查询和Q查询

只有靠单一的第一字参数查询已经很难满足查询要求。此时Django为我们提供了F和Q查询:

图片 63图片 64

# F 使用查询条件的值,专门取对象中某列值的操作

    # from django.db.models import F
    # models.Tb1.objects.update(num=F('num')+1)


# Q 构建搜索条件
    from django.db.models import Q

    #1 Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询
    q1=models.Book.objects.filter(Q(title__startswith='P')).all()
    print(q1)#[<Book: Python>, <Book: Perl>]

    # 2、可以组合使用&,|操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。
    Q(title__startswith='P') | Q(title__startswith='J')

    # 3、Q对象可以用~操作符放在前面表示否定,也可允许否定与不否定形式的组合
    Q(title__startswith='P') | ~Q(pub_date__year=2005)

    # 4、应用范围:

    # Each lookup function that takes keyword-arguments (e.g. filter(),
    #  exclude(), get()) can also be passed one or more Q objects as
    # positional (not-named) arguments. If you provide multiple Q object
    # arguments to a lookup function, the arguments will be “AND”ed
    # together. For example:

    Book.objects.get(
        Q(title__startswith='P'),
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
    )

    #sql:
    # SELECT * from polls WHERE question LIKE 'P%'
    #     AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

    # import datetime
    # e=datetime.date(2005,5,6)  #2005-05-06

    # 5、Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。
    # 正确:
    Book.objects.get(
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
        title__startswith='P')
    # 错误:
    Book.objects.get(
        question__startswith='P',
        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

View Code

admin的配置

admin是django强大效力之一,它能共从数据库中读取数据,显示在页面中,举行田间管理。默认情状下,它的效劳已经特别强劲,假诺您不需要复杂的效用,它早已够用,然则有时,一些卓殊的效应还需要定制,比如寻找功能,下边这一密密麻麻作品就逐渐深刻介绍如何定制符合自己的admin应用。

假设您认为英文界面糟糕用,能够在setting.py 文件中修改以下选项

LANGUAGE_CODE = 'en-us'  #LANGUAGE_CODE = 'zh-hans'

二 注册medel类到admin的二种办法:

<1>   使用register的方法

admin.site.register(Book,MyAdmin)

<2>   使用register的装饰器

@admin.register(Book)

ORM之增(create,save) 

图片 65

from app01.models import *

    #create方式一:   Author.objects.create(name='Alvin')

    #create方式二:   Author.objects.create(**{"name":"alex"})

    #save方式一:     author=Author(name="alvin")
                            author.save()

    #save方式二:     author=Author()
                            author.name="alvin"
                            author.save()

图片 66

**紧要来了------->**那么哪些创设存在一对多或多对多关系的一本书的信息吗?(咋样处理外键关系的字段如一对多的``publisher和多对多的authors)

图片 67 View Code

4.2.2 深度变量的搜寻(万能的句点号)

在到近日停止的例子中,我们通过 context
传递的粗略参数值首假若字符串,但是,模板系统可以分外简短地拍卖更加错综复杂的数据结构,例如list、dictionary和自定义的靶子。在
Django 模板中遍历复杂数据结构的首要性是句点字符 (.)。

图片 68

#最好是用几个例子来说明一下。
# 首先,句点可用于访问列表索引,例如:

>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
'Item 2 is carrots.'

#假设你要向模板传递一个 Python 字典。 要通过字典键访问该字典的值,可使用一个句点:
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
'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)
'The month is 5 and the year is 1993.'

# 这个例子使用了一个自定义的类,演示了通过实例变量加一点(dots)来访问它的属性,这个方法适
# 用于任意的对象。
>>> from django.template import Template, Context
>>> class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name, self.last_name = first_name, last_name
>>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
'Hello, John Smith.'

# 点语法也可以用来引用对象的方法。 例如,每个 Python 字符串都有 upper() 和 isdigit()
# 方法,你在模板中可以使用同样的句点语法来调用它们:
>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
'123 -- 123 -- True'

# 注意这里调用方法时并* 没有* 使用圆括号 而且也无法给该方法传递参数;你只能调用不需参数的
# 方法。

图片 69

5.1 数据库的安排

2.1.1 简单布置

图片 70

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),
]

图片 71

图片 72

    '''
    NOTE:
    1 一旦匹配成功则不再继续
    2 若要从URL 中捕获一个值,只需要在它周围放置一对圆括号。
    3 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
    4 每个正则表达式前面的'r' 是可选的但是建议加上。

一些请求的例子:

    /articles/2005/3/ 不匹配任何URL 模式,因为列表中的第三个模式要求月份应该是两个数字。
    /articles/2003/ 将匹配列表中的第一个模式不是第二个,因为模式按顺序匹配,第一个会首先测试是否匹配。
    /articles/2005/03/ 请求将匹配列表中的第三个模式。Django 将调用函数
                       views.month_archive(request, '2005', '03')。
    '''

图片 73

#设置项是否开启URL访问地址后面不为/跳转至带有/的路径
APPEND_SLASH=True

 

csrf_token标签

用来生成csrf_token的价签,用于防治跨站攻击验证。
其实,这里是会生成一个input标签,和此外表单标签一起付出给后台的。

2.1.6 Including other URLconfs

图片 74

#At any point, your urlpatterns can “include” other URLconf modules. This
#essentially “roots” a set of URLs below other ones.

#For example, here’s an excerpt of the URLconf for the Django website itself.
#It includes a number of other URLconfs:


from django.conf.urls import include, url

urlpatterns = [
   url(r'^admin/', admin.site.urls),
   url(r'^blog/', include('blog.urls')),
]

图片 75

聚集查询和分组查询

<1> aggregate(*args,**kwargs):

  
通过对QuerySet举行测算,重临一个聚合值的字典。aggregate()中每一个参数都指定一个包含在字典中的重回值。即在查询集上生成聚合。

图片 76图片 77

from django.db.models import Avg,Min,Sum,Max

从整个查询集生成统计值。比如,你想要计算所有在售书的平均价钱。Django的查询语法提供了一种方式描述所有
图书的集合。

>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}

aggregate()子句的参数描述了我们想要计算的聚合值,在这个例子中,是Book模型中price字段的平均值

aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的
标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定
一个名称,可以向聚合子句提供它:
>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}


如果你也想知道所有图书价格的最大值和最小值,可以这样查询:
>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}

View Code

<2> annotate(*args,**kwargs):

  
可以通过总结查询结果中每一个目的所提到的对象集合,从而得出总括值(也得以是平均值或总和),即为查询集的每一项生成聚合。

       查询alex出的书总价格      

       图片 78

   
   询问各类作者出的书的总价格,这里就涉及到分组了,分组条件是authors__name

       图片 79   

       查询各种出版社最有利于的书价是有些

       图片 80

3.2.1 render函数

图片 81

---------------render(request, template_name[, context])

结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。

参数:
     request: 用于生成响应的请求对象。

     template_name:要使用的模板的完整名称,可选的参数

     context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。

     content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。

     status:响应的状态码。默认为200。

图片 82

三 精通一些常用的设置技巧

  •     list_display:     指定要呈现的字段
  •     search_fields:  指定搜索的字段
  •     list_filter:        指定列表过滤器
  •     ordering:       指定排序字段

 

图片 83

from django.contrib import admin
from app01.models import *
# Register your models here.

# @admin.register(Book)#----->单给某个表加一个定制
class MyAdmin(admin.ModelAdmin):
    list_display = ("title","price","publisher")
    search_fields = ("title","publisher")
    list_filter = ("publisher",)
    ordering = ("price",)
    fieldsets =[
        (None,               {'fields': ['title']}),
        ('price information', {'fields': ['price',"publisher"], 'classes': ['collapse']}),
    ]

admin.site.register(Book,MyAdmin)
admin.site.register(Publish)
admin.site.register(Author)

图片 84

 

4.2.1  变量(使用双大括号来引用变量)

语法格式:       {{var_name}}

图片 85

----------------------------------Template和Context对象 
>>> python manange.py shell  (进入该django项目的环境)
>>> from django.template import Context, Template
>>> t = Template('My name is {{ name }}.')
>>> c = Context({'name': 'Stephane'})
>>> t.render(c)
'My name is Stephane.'


# 同一模板,多个上下文,一旦有了模板对象,你就可以通过它渲染多个context,无论何时我们都可以
# 像这样使用同一模板源渲染多个context,只进行 一次模板创建然后多次调用render()方法渲染会
# 更为高效:
# Low
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}))

图片 86

Django 模板解析非凡快捷。
大部分的解析工作都是在后台通过对简易正则表明式一次性调用来形成。
这和基于 XML 的模板引擎形成彰着比较,那么些引擎负责了 XML
解析器的开支,且反复比 Django 模板渲染引擎要慢上多少个数据级。

图片 87图片 88

from django.shortcuts import render,HttpResponse
from django.template.loader import get_template #记得导入
# Create your views here.


import datetime
from django.template import Template,Context

# def current_time(req):
    #原始的视图函数
    # now=datetime.datetime.now()
    # html="<html><body>现在时刻:<h1>%s.</h1></body></html>" %now
    # return HttpResponse(html)



# def current_time(req):

      #django模板修改的视图函数
#     now=datetime.datetime.now()
#     t=Template('<html><body>现在时刻是:<h1 style="color:red">{{current_date}}</h1></body></html>')
      #t=get_template('current_datetime.html')
#     c=Context({'current_date':now})
#     html=t.render(c)
#     return HttpResponse(html)

#另一种写法(推荐)

def current_time(req):

    now=datetime.datetime.now()

    return render(req, 'current_datetime.html', {'current_date':now})

View Code

2.1.4 捕获的参数永远是字符串

各种捕获的参数都当做一个一般的Python
字符串传递给视图,无论正则表明式使用的是哪些匹配格局。例如,下面那行URLconf
中:

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

views.year_archive() 的year 参数将是一个字符串

2.2 传递额外的选项给视图函数(领悟)

URLconfs 具有一个钩子,让你传递一个Python
字典作为额外的参数传递给视图函数。

django.conf.urls.url() 函数可以接收一个可选的第六个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。

例如:

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

在这些事例中,对于/blog/2005/请求,Django
将调用views.year_archive(request, year='2005', foo='bar')

本条技能在Syndication 框架中运用,来传递元数据和甄选给视图。

4.1 模板系统的介绍

你也许曾经注意到我们在例子视图中回到文本的法子有点特别。
也就是说,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)来贯彻那种形式,这就是本章要具体探讨的题目。

python的模版:HTML代码+逻辑控制代码

加载标签库:自定义filter和simple_tag**

a、在app中创建templatetags模块(必须的)

b、创立任意 .py 文件,如:my_tags.py

图片 89图片 90

from django import template
from django.utils.safestring import mark_safe

register = template.Library()   #register的名字是固定的,不可改变


@register.filter
def filter_multi(v1,v2):
    return  v1 * v2


@register.simple_tag
def simple_tag_multi(v1,v2):
    return  v1 * v2


@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)
复制代码

View Code

c、在拔取自定义simple_tag和filter的html文件中导入以前创造的
my_tags.py :{% load my_tags %}

d、使用simple_tag和filter(怎样调用)

-------------------------------.html
{% load xxx %}   #首行


 # num=12
{{ num|filter_multi:2 }} #24

{{ num|filter_multi:"[22,333,4444]" }}


{% simple_tag_multi 2 5 %}  参数不限,但不能放在if for语句中
{% simple_tag_multi num 5 %}

 

e、在settings中的INSTALLED_APPS配置当前app,不然django不可能找到自定义的simple_tag.

注意:

filter可以用在if等语句后,simple_tag不可以

{% if num|filter_multi:30 > 100 %}
    {{ num|filter_multi:30 }}
{% endif %}

{% verbatim %}

禁止render

{% verbatim %}
         {{ hello }}
{% endverbatim %}

3.2.2 redirect函数

图片 91

-----------------------------------url.py

 url(r"login",   views.login),
 url(r"yuan_back",   views.yuan_back),

-----------------------------------views.py
def login(req):
    if req.method=="POST":
        if 1:
            # return redirect("/yuan_back/")
            name="yuanhao"

            return render(req,"my backend.html",locals())

    return render(req,"login.html",locals())


def yuan_back(req):

    name="苑昊"

    return render(req,"my backend.html",locals())

-----------------------------------login.html

<form action="/login/" method="post">
    <p>姓名<input type="text" name="username"></p>
    <p>性别<input type="text" name="sex"></p>
    <p>邮箱<input type="text" name="email"></p>
    <p><input type="submit" value="submit"></p>
</form>
-----------------------------------my backend.html
<h1>用户{{ name }}你好</h1>

#总结: render和redirect的区别:
#   1 if render的页面需要模板语言渲染,需要的将数据库的数据加载到html,那么所有的这一部分
#     除了写在yuan_back的视图函数中,必须还要写在login中,代码重复,没有解耦.

#   2 the most important: url没有跳转到/yuan_back/,而是还在/login/,所以当刷新后
#     又得重新登录.

图片 92

四 Template

4.2 模板协助的语法

网站地图xml地图