一周后的重温

作者: 网络编程  发布:2019-08-29

数据库的布局

Django

 

1    django默许协理sqlite,mysql, oracle,postgresql数据库。

     <1> sqlite

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

     <2> mysql

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

一 什么是web框架?

框架,即framework,特指为杀鸡取卵两个开放性难题而规划的全体自然约束性的援救结构,使用框架能够帮您飞速支付特定的系统,轻便地说,就是你用旁人搭建好的戏台来做表演。

对此全体的Web应用,本质上实际正是二个socket服务端,顾客的浏览器其实正是七个socket客商端。

图片 1图片 2

import socket

def handle_request(client):

    buf = client.recv(1024)
    client.send("HTTP/1.1 200 OKrnrn".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---------------------------**

2    mysql驱动程序

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

step 1:

图片 3图片 4

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

注意:

图片 5图片 6

整个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

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

图片 7

一经大家想要改换数据库,必要修改如下:

图片 8

 1 DATABASES = {
 2 
 3     'default': {
 4 
 5         'ENGINE': 'django.db.backends.mysql', 
 6 
 7         'NAME': 'books',    #你的数据库名称
 8 
 9         'USER': 'root',   #你的数据库用户名
10 
11         'PASSWORD': '', #你的数据库密码
12 
13         'HOST': '', #你的数据库主机,留空默认为localhost
14 
15         'PORT': '3306', #你的数据库端口
16 
17     }
18 
19 }

注意:

图片 9图片 10

 1 NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建
 2 
 3 USER和PASSWORD分别是数据库的用户名和密码。
 4 
 5 设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。
 6 
 7 然后,启动项目,会报错:no module named MySQLdb
 8 
 9 这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb对于py3有很大问题,所以我们需要的驱动是PyMySQL
10 
11 所以,我们只需要找到项目名文件下的__init__,在里面写入:
12 
13 import pymysql
14 pymysql.install_as_MySQLdb()
15 
16 问题解决!

View Code

step 2

图片 11图片 12

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

ORM(对象关系映射)

用于落到实处面向对象编制程序语言里不一致品种系统的多寡里面包车型客车改换,换言之,正是用面向对象的秘诀去操作数据库的创办表以及增加和删除改查等操作。

可取: 1 ORM使得大家的通用数据库交互变得简单易行,何况完全不用思虑该死的SQL语句。神速支付,因而而来。

          2 足以制止某些新手工业程师写sql语句带来的属性难点。

            比如我们查询User表中的全数字段:

图片 13

 新手大概会用select * from  auth_user,那样会因为多了一个非凡动作而影响功能的。

 缺点:1  性质有所捐躯,然而今后的种种ORM框架都在尝试各样措施,譬喻缓存,延迟加载登来缓慢解决那些标题。效果很明朗。

          2  对此个别复杂查询,ORM依然不可能,为了消除那一个标题,ORM一般也帮衬写raw sql。

          3  通过QuerySet的query属性查询相应操作的sql语句

1 author_obj=models.Author.objects.filter(id=2)
2 print(author_obj.query)

 下边要开首学习Django ORM语法了,为了更加好的精通,大家来做四个中央的 书籍/小编/出版商 数据库结构。 大家这么做是因为 那是二个分明的事例,很多SQL有关的书本也常用那些比喻。

step3

图片 14图片 15

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

表(模型)的创建:

实例:大家来要是上边这一个概念,字段和事关

作者模型:三个小编有姓名。

我详细模型:把笔者的实际情况放到详细情形表,满含性别,email地址和出破壳日期,小编详细情形模型和小编模型之间是一定的关系(one-to-one)(类似于每一个人和她的居民身份证之间的涉及),在大多数情景下大家并不必要将他们拆分成两张表,这里只是引出一对一的定义。

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

书籍模型:书籍有书名和出版日期,一本书恐怕会有七个小编,二个我也能够写多本书,所以笔者和书本的关联正是多对多的关系关系(many-to-many),一本书只应该由三个出版商出版,所以出版商和书籍是一对多关系关系(one-to-many),也被称作外键。

图片 16图片 17

 1 from django.db import models<br>
 2 class Publisher(models.Model):
 3     name = models.CharField(max_length=30, verbose_name="名称")
 4     address = models.CharField("地址", max_length=50)
 5     city = models.CharField('城市',max_length=60)
 6     state_province = models.CharField(max_length=30)
 7     country = models.CharField(max_length=50)
 8     website = models.URLField()
 9  
10     class Meta:
11         verbose_name = '出版商'
12         verbose_name_plural = verbose_name
13  
14     def __str__(self):
15         return self.name
16  
17 class Author(models.Model):
18     name = models.CharField(max_length=30)
19     def __str__(self):
20         return self.name
21  
22 class AuthorDetail(models.Model):
23     sex = models.BooleanField(max_length=1, choices=((0, '男'),(1, '女'),))
24     email = models.EmailField()
25     address = models.CharField(max_length=50)
26     birthday = models.DateField()
27     author = models.OneToOneField(Author)
28  
29 class Book(models.Model):
30     title = models.CharField(max_length=100)
31     authors = models.ManyToManyField(Author)
32     publisher = models.ForeignKey(Publisher)
33     publication_date = models.DateField()
34     price=models.DecimalField(max_digits=5,decimal_places=2,default=10)
35     def __str__(self):
36         return self.title

View Code

注意1:记得在settings里的INSTALLED_应用软件S中参预'app01',然后再一齐数据库。

注意2: models.ForeignKey("Publish") & models.ForeignKey(Publish)

深入分析代码:

       <1>  各种数据模型都以django.db.models.Model的子类,它的父类Model包涵了装有须要的和数据库交互的方法。并提供了贰个简要介绍美丽的概念数据库字段的语法。

       <2>  各个模型也就是单个数据库表(多对多关系区别,会多生成一张关系表),每一种属性也是以此表中的字段。属性名正是字段名,它的花色(举个例子Char菲尔德)相当于数据库的字段类型(举例varchar)。大家能够小心下另外的系列都和数据Curry的什么样字段对应。

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

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

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

             多对多:(ManyToManyField) 自动创制第三张表(当然大家也足以本人创设第三张表:三个foreign key)

       <4>  模型常用的字段类型参数

图片 18图片 19

<1> CharField
        #字符串字段, 用于较短的字符串.
        #CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数.

<2> IntegerField
       #用于保存一个整数.

<3> FloatField
        # 一个浮点数. 必须 提供两个参数:
        #
        # 参数    描述
        # max_digits    总位数(不包括小数点和符号)
        # decimal_places    小数位数
                # 举例来说, 要保存最大值为 999 (小数点后保存2位),你要这样定义字段:
                #
                # models.FloatField(..., max_digits=5, decimal_places=2)
                # 要保存最大值一百万(小数点后保存10位)的话,你要这样定义:
                #
                # models.FloatField(..., max_digits=19, decimal_places=10)
                # admin 用一个文本框(<input type="text">)表示该字段保存的数据.

<4> AutoField
        # 一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段; 
        # 自定义一个主键:my_id=models.AutoField(primary_key=True)
        # 如果你不指定主键的话,系统会自动添加一个主键字段到你的 model.

<5> BooleanField
        # A true/false field. admin 用 checkbox 来表示此类字段.

<6> TextField
        # 一个容量很大的文本字段.
        # admin 用一个 <textarea> (文本区域)表示该字段数据.(一个多行编辑框).

<7> EmailField
        # 一个带有检查Email合法性的 CharField,不接受 maxlength 参数.

<8> DateField
        # 一个日期字段. 共有下列额外的可选参数:
        # Argument    描述
        # auto_now    当对象被保存时,自动将该字段的值设置为当前时间.通常用于表示 "last-modified" 时间戳.
        # auto_now_add    当对象首次被创建时,自动将该字段的值设置为当前时间.通常用于表示对象创建时间.
        #(仅仅在admin中有意义...)

<9> DateTimeField
        #  一个日期时间字段. 类似 DateField 支持同样的附加选项.

<10> ImageField
        # 类似 FileField, 不过要校验上传对象是否是一个合法图片.#它有两个可选参数:height_field和width_field,
        # 如果提供这两个参数,则图片将按提供的高度和宽度规格保存.     
<11> FileField
     # 一个文件上传字段.
     #要求一个必须有的参数: upload_to, 一个用于保存上载文件的本地文件系统路径. 这个路径必须包含 strftime #formatting, 
     #该格式将被上载文件的 date/time 
     #替换(so that uploaded files don't fill up the given directory).
     # admin 用一个<input type="file">部件表示该字段保存的数据(一个文件上传部件) .

     #注意:在一个 model 中使用 FileField 或 ImageField 需要以下步骤:
            #(1)在你的 settings 文件中, 定义一个完整路径给 MEDIA_ROOT 以便让 Django在此处保存上传文件. 
            # (出于性能考虑,这些文件并不保存到数据库.) 定义MEDIA_URL 作为该目录的公共 URL. 要确保该目录对 
            #  WEB服务器用户帐号是可写的.
            #(2) 在你的 model 中添加 FileField 或 ImageField, 并确保定义了 upload_to 选项,以告诉 Django
            # 使用 MEDIA_ROOT 的哪个子目录保存上传文件.你的数据库中要保存的只是文件的路径(相对于 MEDIA_ROOT). 
            # 出于习惯你一定很想使用 Django 提供的 get_<#fieldname>_url 函数.举例来说,如果你的 ImageField 
            # 叫作 mug_shot, 你就可以在模板中以 {{ object.#get_mug_shot_url }} 这样的方式得到图像的绝对路径.

<12> URLField
      # 用于保存 URL. 若 verify_exists 参数为 True (默认), 给定的 URL 会预先检查是否存在( 即URL是否被有效装入且
      # 没有返回404响应).
      # admin 用一个 <input type="text"> 文本框表示该字段保存的数据(一个单行编辑框)

<13> NullBooleanField
       # 类似 BooleanField, 不过允许 NULL 作为其中一个选项. 推荐使用这个字段而不要用 BooleanField 加 null=True 选项
       # admin 用一个选择框 <select> (三个可选择的值: "Unknown", "Yes" 和 "No" ) 来表示这种字段数据.

<14> SlugField
       # "Slug" 是一个报纸术语. slug 是某个东西的小小标记(短签), 只包含字母,数字,下划线和连字符.#它们通常用于URLs
       # 若你使用 Django 开发版本,你可以指定 maxlength. 若 maxlength 未指定, Django 会使用默认长度: 50.  #在
       # 以前的 Django 版本,没有任何办法改变50 这个长度.
       # 这暗示了 db_index=True.
       # 它接受一个额外的参数: prepopulate_from, which is a list of fields from which to auto-#populate 
       # the slug, via JavaScript,in the object's admin form: models.SlugField
       # (prepopulate_from=("pre_name", "name"))prepopulate_from 不接受 DateTimeFields.

<13> XMLField
        #一个校验值是否为合法XML的 TextField,必须提供参数: schema_path, 它是一个用来校验文本的 RelaxNG schema #的文件系统路径.

<14> FilePathField
        # 可选项目为某个特定目录下的文件名. 支持三个特殊的参数, 其中第一个是必须提供的.
        # 参数    描述
        # path    必需参数. 一个目录的绝对文件系统路径. FilePathField 据此得到可选项目. 
        # Example: "/home/images".
        # match    可选参数. 一个正则表达式, 作为一个字符串, FilePathField 将使用它过滤文件名.  
        # 注意这个正则表达式只会应用到 base filename 而不是
        # 路径全名. Example: "foo.*.txt^", 将匹配文件 foo23.txt 却不匹配 bar.txt 或 foo23.gif.
        # recursive可选参数.要么 True 要么 False. 默认值是 False. 是否包括 path 下面的全部子目录.
        # 这三个参数可以同时使用.
        # match 仅应用于 base filename, 而不是路径全名. 那么,这个例子:
        # FilePathField(path="/home/images", match="foo.*", recursive=True)
        # ...会匹配 /home/images/foo.gif 而不匹配 /home/images/foo/bar.gif

<15> IPAddressField
        # 一个字符串形式的 IP 地址, (i.e. "24.124.1.30").
<16># CommaSeparatedIntegerField
        # 用于存放逗号分隔的整数值. 类似 CharField, 必须要有maxlength参数.

View Code

      <5>  Field首要参数

图片 20图片 21

<1> null : 数据库中字段是否可以为空

    <2> blank: django的 Admin 中添加数据时是否可允许空值

    <3> default:设定缺省值

    <4> editable:如果为假,admin模式下将不能改写。缺省为真

    <5> primary_key:设置主键,如果没有设置django创建表时会自动加上:
        id = meta.AutoField('ID', primary_key=True)
        primary_key=True implies blank=False, null=False and unique=True. Only one
        primary key is allowed on an object.

    <6> unique:数据唯一

    <7> verbose_name  Admin中字段的显示名称

    <8> validator_list:有效性检查。非有效产生 django.core.validators.ValidationError 错误


    <9> db_column,db_index 如果为真将为此字段创建索引

    <10>choices:一个用来选择值的2维元组。第一个值是实际存储的值,第二个用来方便进行选择。
                如SEX_CHOICES= (( ‘F’,'Female’),(‘M’,'Male’),)
                gender = models.CharField(max_length=2,choices = SEX_CHOICES)

View Code

step4

图片 22图片 23

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框架啦!

表的操作(增加和删除改查):

**-------------------------------------增(create  ,  save) -------------------------------**

 1 from app01.models import *
 2 
 3     #create方式一:   Author.objects.create(name='Alvin')
 4 
 5     #create方式二:   Author.objects.create(**{"name":"alex"})
 6 
 7     #save方式一:     author=Author(name="alvin")
 8                     author.save()
 9 
10     #save方式二:     author=Author()
11                     author.name="alvin"
12                     author.save()

对此一对多、多对多的操作:

图片 24图片 25

 1 #一对多(ForeignKey):
 2 
 3     #方式一: 由于绑定一对多的字段,比如publish,存到数据库中的字段名叫publish_id,所以我们可以直接给这个
 4     #       字段设定对应值:
 5            Book.objects.create(title='php',
 6                                publisher_id=2,   #这里的2是指为该book对象绑定了Publisher表中id=2的行对象
 7                                publication_date='2017-7-7',
 8                                price=99)
 9 
10 
11     #方式二:
12     #       <1> 先获取要绑定的Publisher对象:
13         pub_obj=Publisher(name='河大出版社',address='保定',city='保定',
14                 state_province='河北',country='China',website='http://www.hbu.com')
15     OR  pub_obj=Publisher.objects.get(id=1)
16 
17     #       <2>将 publisher_id=2 改为  publisher=pub_obj
18 
19 #多对多(ManyToManyField()):
20 
21     author1=Author.objects.get(id=1)
22     author2=Author.objects.filter(name='alvin')[0]
23     book=Book.objects.get(id=1)
24     book.authors.add(author1,author2)
25     #等同于:
26     book.authors.add(*[author1,author2])
27     book.authors.remove(*[author1,author2])
28     #-------------------
29     book=models.Book.objects.filter(id__gt=1)
30     authors=models.Author.objects.filter(id=1)[0]
31     authors.book_set.add(*book)
32     authors.book_set.remove(*book)
33     #-------------------
34     book.authors.add(1)
35     book.authors.remove(1)
36     authors.book_set.add(1)
37     authors.book_set.remove(1)
38 
39 #注意: 如果第三张表是通过models.ManyToManyField()自动创建的,那么绑定关系只有上面一种方式
40 #     如果第三张表是自己创建的:
41      class Book2Author(models.Model):
42             author=models.ForeignKey("Author")
43             Book=  models.ForeignKey("Book")
44 #     那么就还有一种方式:
45             author_obj=models.Author.objects.filter(id=2)[0]
46             book_obj  =models.Book.objects.filter(id=3)[0]
47 
48             s=models.Book2Author.objects.create(author_id=1,Book_id=2)
49             s.save()
50             s=models.Book2Author(author=author_obj,Book_id=1)
51             s.save()

View Code

**-----------------------------------------删(delete) ---------------------------------------------**

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

我们表面上删除了一条音信,实际却删除了三条,因为我们删除的那本书在Book_authors表中有两条相关音信,这种删除格局正是django暗中同意的级联删除。

假若果多对多的涉及: remove()和clear()方法: 

 1 #正向
 2 book = models.Book.objects.filter(id=1)
 3 
 4 #删除第三张表中和女孩1关联的所有关联信息
 5 book.author.clear()        #清空与book中id=1 关联的所有数据
 6 book.author.remove(2)  #可以为id
 7 book.author.remove(*[1,2,3,4])     #可以为列表,前面加*
 8 
 9 #反向
10 author = models.Author.objects.filter(id=1)
11 author.book_set.clear() #清空与boy中id=1 关联的所有数据

**-----------------------------------------改(update和save) ----------------------------------------**

实例:

图片 26

注意:

<1> 第三种办法修改无法用get的来头是:update是QuerySet对象的方式,get再次来到的是叁个model对象,它从不update方法,而filter再次回到的是一个QuerySet对象(filter里面包车型大巴规范恐怕有四个原则适合,比如name='alvin',也是有三个name='alvin'的行数据)。

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

图片 27图片 28

 1 #---------------- update方法直接设定对应属性----------------
 2     models.Book.objects.filter(id=3).update(title="PHP")
 3     ##sql:
 4     ##UPDATE "app01_book" SET "title" = 'PHP' WHERE "app01_book"."id" = 3; args=('PHP', 3)
 5 
 6 
 7 #--------------- save方法会将所有属性重新设定一遍,效率低-----------
 8     obj=models.Book.objects.filter(id=3)[0]
 9     obj.title="Python"
10     obj.save()
11 # SELECT "app01_book"."id", "app01_book"."title", "app01_book"."price", 
12 # "app01_book"."color", "app01_book"."page_num", 
13 # "app01_book"."publisher_id" FROM "app01_book" WHERE "app01_book"."id" = 3 LIMIT 1; 
14 # 
15 # UPDATE "app01_book" SET "title" = 'Python', "price" = 3333, "color" = 'red', "page_num" = 556,
16 # "publisher_id" = 1 WHERE "app01_book"."id" = 3;

View Code

  在这一个例子里我们得以看来Django的save()方法创新了非但是title列的值,还恐怕有立异了富有的列。 若title以外的列有比非常的大概率会被另外的进程所退换的情景下,只改动title列鲜明是更进一竿精明的。退换某一点名的列,大家得以调用结果集(QuerySet)对象的update()方法,与之等同的SQL语句变得更敏捷,并且不会挑起竞态条件。

另外,update()方法对于别的结果集(QuerySet)均有效,那意味着你能够并且更新多条记录update()方法会重回多个整型数值,表示受影响的记录条数。

小心,这里因为update重返的是八个整形,所以无法用query属性;对于每一回创制三个对象,想体现相应的raw sql,必要在settings加上日志记录部分:

图片 29图片 30

 1 LOGGING = {
 2     'version': 1,
 3     'disable_existing_loggers': False,
 4     'handlers': {
 5         'console':{
 6             'level':'DEBUG',
 7             'class':'logging.StreamHandler',
 8         },
 9     },
10     'loggers': {
11         'django.db.backends': {
12             'handlers': ['console'],
13             'propagate': True,
14             'level':'DEBUG',
15         },
16     }
17 }
18 
19 LOGGING

View Code

瞩目:如若是多对多的改:

1 obj=Book.objects.filter(id=1)[0]
2     author=Author.objects.filter(id__gt=2)
3 
4     obj.author.clear()
5     obj.author.add(*author)

---------------------------------------查(filter,value等) -------------------------------------**

---------->查询API:

图片 31图片 32

# 查询相关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。

View Code

补充:

图片 33图片 34

#扩展查询,有时候DJANGO的查询API不能方便的设置查询条件,提供了另外的扩展查询方法extra:
#extra(select=None, where=None, params=None, tables=None,order_by=None, select_params=None

(1)  Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
(2)  Blog.objects.extra(
        select=SortedDict([('a', '%s'), ('b', '%s')]),
        select_params=('one', 'two'))

(3)  q = Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
     q = q.extra(order_by = ['-is_recent'])

(4)  Entry.objects.extra(where=['headline=%s'], params=['Lennon'])  

extra

View Code

---------->惰性机制:

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

QuerySet特点:

       <1>  可迭代的

       <2>  可切片

图片 35图片 36

 1 #objs=models.Book.objects.all()#[obj1,obj2,ob3...]
 2 
 3     #QuerySet:   可迭代
 4 
 5     # for obj in objs:#每一obj就是一个行对象
 6     #     print("obj:",obj)
 7     # QuerySet:  可切片
 8 
 9     # print(objs[1])
10     # print(objs[1:4])
11     # print(objs[::-1])

View Code

QuerySet的登时使用:

图片 37图片 38

<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

---------->对象查询,单表条件查询,多表口径关联合检查询

图片 39图片 40

#--------------------对象形式的查找--------------------------
    # 正向查找
    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
    #一对多和多对多在这里用法没区别

View Code

潜心:条件查询即与指标查询相应,是指在filter,values等方式中的通过__来鲜明询问条件。

---------->聚合查询和分组查询

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

   通过对QuerySet进行测算,重返二个聚合值的字典。aggregate()中每一个参数都内定贰个分包在字典中的再次回到值。即在查询集上生成聚合。

图片 41图片 42

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出的书总价格                   

图片 43

        查询各样我出的书的总价格,这里就关系到分组了,分组条件是authors__name

图片 44

         查询种种出版社最利于的书价是稍稍

图片 45

---------->F查询和Q查询

仅仅靠单纯的机要字参数查询已经很难满意查询必要。此时Django为大家提供了F和Q查询:

图片 46图片 47

 1 # F 使用查询条件的值,专门取对象中某列值的操作
 2 
 3     # from django.db.models import F
 4     # models.Tb1.objects.update(num=F('num') 1)
 5 
 6 
 7 # Q 构建搜索条件
 8     from django.db.models import Q
 9 
10     #1 Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询
11     q1=models.Book.objects.filter(Q(title__startswith='P')).all()
12     print(q1)#[<Book: Python>, <Book: Perl>]
13 
14     # 2、可以组合使用&,|操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。
15     Q(title__startswith='P') | Q(title__startswith='J')
16 
17     # 3、Q对象可以用~操作符放在前面表示否定,也可允许否定与不否定形式的组合
18     Q(title__startswith='P') | ~Q(pub_date__year=2005)
19 
20     # 4、应用范围:
21 
22     # Each lookup function that takes keyword-arguments (e.g. filter(),
23     #  exclude(), get()) can also be passed one or more Q objects as
24     # positional (not-named) arguments. If you provide multiple Q object
25     # arguments to a lookup function, the arguments will be “AND”ed
26     # together. For example:
27 
28     Book.objects.get(
29         Q(title__startswith='P'),
30         Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
31     )
32 
33     #sql:
34     # SELECT * from polls WHERE question LIKE 'P%'
35     #     AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
36 
37     # import datetime
38     # e=datetime.date(2005,5,6)  #2005-05-06
39 
40     # 5、Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。
41     # 正确:
42     Book.objects.get(
43         Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
44         title__startswith='P')
45     # 错误:
46     Book.objects.get(
47         question__startswith='P',
48         Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

View Code

二 MVC和MTV模式

盛名的MVC方式:所谓MVC便是把web应用分为模型(M),调节器(C),视图(V)三层;他们之间以一种插件似的,松耦合的章程连接在联名。

模型担负作业对象与数据库的指标(ORM),视图担当与顾客的相互(页面),调整器(C)接受顾客的输入调用模型和视图完结客商的央浼。

                   图片 48

Django的MTV格局本质上与MVC情势尚未怎么差异,也是各组件之间为了维持松耦合关系,只是概念上有些许分歧,Django的M电视分别代表:

       Model(模型):担当作业对象与数据库的靶子(ORM)

       Template(模版):肩负什么把页面突显给客户

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

       其余,Django还会有贰个url分发器,它的功用是将一个个ULX570L的页面诉求分发给分歧的view处理,view再调用相应的Model和Template

图片 49

raw sql

django中models的操作,也是调用了ORM框架来落成的,pymysql 或许mysqldb,所以大家也得以采取原生的SQL语句来操作数据库!

 

 三 django的流水生产线和命令行工具

django达成流程

图片 50图片 51

django
    #安装: pip3 install django

          添加环境变量

    #1  创建project
       django-admin startproject mysite

       ---mysite

          ---settings.py
          ---url.py
          ---wsgi.py

       ---- manage.py(启动文件)  

    #2  创建APP       
       python mannage.py startapp  app01

    #3  settings配置

       TEMPLATES

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

       STATIC_URL = '/static/' 
       #  我们只能用 STATIC_URL,但STATIC_URL会按着你的STATICFILES_DIRS去找#4  根据需求设计代码
           url.py
           view.py

    #5  使用模版
       render(req,"index.html")   

    #6  启动项目
       python manage.py runserver  127.0.0.1:8090

    #7  连接数据库,操作数据
       model.py

View Code

django的命令行工具

django-admin.py 是Django的贰个用以管理任务的命令行工具,manage.py是对django-admin.py的归纳包装,每两个Django Project里都会有贰个mannage.py。

<1> 创造二个django工程 : django-admin.py startproject mysite

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

        图片 52

  • manage.py ----- Django项目里面包车型地铁工具,通过它能够调用django shell和数据库等。
  • settings.py ---- 包括了类其余暗许设置,包含数据库音讯,调试标识以及任何一些做事的变量。
  • urls.py ----- 担当把UHavalL格局映射到应用程序。

<2>在mysite目录下创办blog应用: python manage.py startapp blog

        图片 53

<3>启动django项目:python manage.py runserver 8080

       这样我们的django就开动起来了!当大家拜谒:

       图片 54

<4>生成同步数据库的剧本:python manage.py makemigrations  

                     同步数据库:  python manage.py migrate   

       注意:在支付进程中,数据库同步误操作之后,难免会蒙受前面无法一齐成功的情形,化解那几个主题材料的一个粗略凶横方法是把migrations目录下

                的脚本(除__init__.py之外)全体删掉,再把数据库删掉之后创建三个新的数据库,数据库同步操作再重新做二遍。            

<5>当我们会见

       图片 55

       所以我们需求为走入那些项指标后台创制一级管理员:python manage.py createsuperuser安装好顾客名和密码后便可记名啦!

<6>清空数据库:python manage.py  flush

<7>查询有些命令的详细音讯: django-admin.py  help  startapp

       admin 是Django 自带的三个后台数据库管理种类。

<8>运营交互分界面 :python manage.py  shell

     这些命令和一直运营 python 步入 shell 的分别是:你可以在那个 shell 里面调用当前项指标 models.py 中的 API,对于操作数据,还会有一对小测验特别有利。

<9> 顶点上输入python manage.py 能够见见详细的列表,在忘记子名称的时候特意有用

实例练习1-提交数据并显示

图片 56图片 57

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>创建个人信息</h1>

<form action="/userInfor/" 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>

<hr>

<h1>信息展示</h1>

<table border="1">

    <tr>
        <td>姓名</td>
        <td>性别</td>
        <td>邮箱</td>
    </tr>
    {% for i in info_list %}

        <tr>
            <td>{{ i.username }}</td>
            <td>{{ i.sex }}</td>
            <td>{{ i.email }}</td>
        </tr>

    {% endfor %}

</table>

</body>
</html>


-----------------------url.py---------------------------------------
url(r'^userInfor/', views.userInfor)

-----------------------views.py--------------------------------------

info_list=[]

def userInfor(req):

    if req.method=="POST":
        username=req.POST.get("username",None)
        sex=req.POST.get("sex",None)
        email=req.POST.get("email",None)

        info={"username":username,"sex":sex,"email":email}
        info_list.append(info)

    return render(req,"userInfor.html",{"info_list":info_list})

View Code

实例演习2-交给数据并体现(数据库)

图片 58图片 59

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>创建个人信息</h1>

<form action="/userInfor/" 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>

<hr>

<h1>信息展示</h1>

<table border="1">

    <tr>
        <td>姓名</td>
        <td>性别</td>
        <td>邮箱</td>
    </tr>
    {% for i in info_list %}

        <tr>
            <td>{{ i.username }}</td>
            <td>{{ i.sex }}</td>
            <td>{{ i.email }}</td>
        </tr>

    {% endfor %}

</table>

</body>
</html>


----------------------------------------------models.py
from django.db import models

# Create your models here.


class UserInfor(models.Model):

    username=models.CharField(max_length=64)
    sex=models.CharField(max_length=64)
    email=models.CharField(max_length=64)

----------------------------------------------views.py

from django.shortcuts import render

from app01 import models
# Create your views here.


def userInfor(req):

    if req.method=="POST":
        u=req.POST.get("username",None)
        s=req.POST.get("sex",None)
        e=req.POST.get("email",None)


       #---------表中插入数据方式一
            # info={"username":u,"sex":e,"email":e}
            # models.UserInfor.objects.create(**info)

       #---------表中插入数据方式二
        models.UserInfor.objects.create(
            username=u,
            sex=s,
            email=e
        )

        info_list=models.UserInfor.objects.all()

        return render(req,"userInfor.html",{"info_list":info_list})

    return render(req,"userInfor.html")

View Code

四 Django的安插文件(settings)

静态文件设置:

图片 60图片 61

一、概述:

     #静态文件交由Web服务器处理,Django本身不处理静态文件。简单的处理逻辑如下(以nginx为例):

     #          URI请求-----> 按照Web服务器里面的配置规则先处理,以nginx为例,主要求配置在nginx.
                             #conf里的location

                         |---------->如果是静态文件,则由nginx直接处理

                         |---------->如果不是则交由Django处理,Django根据urls.py里面的规则进行匹配

    # 以上是部署到Web服务器后的处理方式,为了便于开发,Django提供了在开发环境的对静态文件的处理机制,方法是这样:

    #1、在INSTALLED_APPS里面加入'django.contrib.staticfiles',

    #2、在urls.py里面加入
       if settings.DEBUG:  
           urlpatterns  = patterns('', url(r'^media/(?P<path>.*)$', 
           'django.views.static.serve', {'document_root': settings.MEDIA_ROOT }),   
            url(r'^static/(?P<path>.*)$',
          'django.views.static.serve',{'document_root':settings.STATIC_ROOT}), )  

    # 3、这样就可以在开发阶段直接使用静态文件了。

二、MEDIA_ROOT和MEDIA_URL

        #而静态文件的处理又包括STATIC和MEDIA两类,这往往容易混淆,在Django里面是这样定义的:

        #MEDIA:指用户上传的文件,比如在Model里面的FileFIeld,ImageField上传的文件。如果你定义

        #MEDIA_ROOT=c:tempmedia,那么File=models.FileField(upload_to="abc/")#,上传的文件就会被保存到c:tempmediaabc  
        #eg:
            class blog(models.Model):  
                   Title=models.charField(max_length=64)  
                   Photo=models.ImageField(upload_to="photo") 
        #     上传的图片就上传到c:tempmediaphoto,而在模板中要显示该文件,则在这样写
        #在settings里面设置的MEDIA_ROOT必须是本地路径的绝对路径,一般是这样写:
                 BASE_DIR= os.path.abspath(os.path.dirname(__file__))  
                 MEDIA_ROOT=os.path.join(BASE_DIR,'media/').replace('\','/') 

        #MEDIA_URL是指从浏览器访问时的地址前缀,举个例子:
            MEDIA_ROOT=c:tempmediaphoto  
            MEDIA_URL="/data/"
        #在开发阶段,media的处理由django处理:

        #    访问http://localhost/data/abc/a.png就是访问c:tempmediaphotoabca.png

        #    在模板里面这样写<img src="{{MEDIA_URL}}abc/a.png">

        #    在部署阶段最大的不同在于你必须让web服务器来处理media文件,因此你必须在web服务器中配置,
        #  以便能让web服务器能访问media文件
        #    以nginx为例,可以在nginx.conf里面这样:

                 location ~/media/{
                       root/temp/
                       break;
                    }

        #    具体可以参考如何在nginx部署django的资料。

三、STATIC_ROOT和STATIC_URL、
    STATIC主要指的是如css,js,images这样文件,在settings里面可以配置STATIC_ROOT和STATIC_URL,
    配置方式与MEDIA_ROOT是一样的,但是要注意

    #STATIC文件一般保存在以下位置:

    #1、STATIC_ROOT:在settings里面设置,一般用来放一些公共的js,css,images等。

    #2、app的static文件夹,在每个app所在文夹均可以建立一个static文件夹,然后当运行collectstatic时,
    #    Django会遍历INSTALL_APPS里面所有app的static文件夹,将里面所有的文件复制到STATIC_ROOT。因此,
    #   如果你要建立可复用的app,那么你要将该app所需要的静态文件放在static文件夹中。

    # 也就是说一个项目引用了很多app,那么这个项目所需要的css,images等静态文件是分散在各个app的static文件的,比
    #  较典型的是admin应用。当你要发布时,需要将这些分散的static文件收集到一个地方就是STATIC_ROOT。

    #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>

View Code

其他首要参数设置:

APPEND_SLASH
       Default: True
       When set to True, if the request URL does not match any of the patterns in the URLconf and it 
       doesn’t end in a slash, an HTTP redirect is issued to the same URL with a slash appended. Note 
       that the redirect may cause any data submitted in a POST request to be lost.

五 Django UHighlanderL (路由系统)

     U哈弗L配置(UKoleosLconf)就像是Django 所支撑网址的目录。它的面目是UEvoqueL方式以及要为该URubiconL格局调用的视图函数之间的映射表;你正是以这种情势告知Django,对于那一个U陆风X8L调用这段代码,对于丰裕UTiguanL调用这段代码。

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

参数说明:

  • 叁个正则表明式字符串
  • 贰个可调用对象,平时为二个视图函数或四个钦定视图函数路线的字符串
  • 可选的要传递给视图函数的暗中认可参数(字典格局)
  • 一个可选的name参数

5.1 Here’s a sample URLconf:

from django.conf.urls import url
from django.contrib import admin

from app01 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})/$', views.year_archive),  #no_named group

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

]

Note:

图片 62图片 63

#1   There’s no need to add a leading slash, because every URL has that. For
#    example, it’s ^articles, not ^/articles.

#2   A request to /articles/2005/03/ would match the third entry in the list.
#    Django would call the function views.month_archive(request, '2005', '03').

#3   /articles/2005/3/ would not match any URL patterns

#4   /articles/2003/ would match the first pattern in the list, not the second one

#5   /articles/2003/03/03/ would match the final pattern. Django would call the
#    functionviews.article_detail(request, '2003', '03', '03').

View Code

5.2 Named groups

      The above example used simple, non-named regular-expression groups (via parenthesis) to capture bits of the URL and pass them as positional arguments to a view. In more advanced usage, it’s possible to use named regular-expression groups to capture URL bits and pass them as keyword arguments to a view.

       In Python regular expressions, the syntax for named regular-expression groups is (?P<name>pattern), where name is the name of the group and pattern is some pattern to match.

Here’s the above example URLconf, rewritten to use named groups:

图片 64图片 65

import re

ret=re.search('(?P<id>d{3})/(?P<name>w{3})','weeew34ttt123/ooo')

print(ret.group())
print(ret.group('id'))
print(ret.group('name'))

ready

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

       This accomplishes exactly the same thing as the previous example, with one subtle difference: The captured values are passed to view functions as keyword arguments rather than positional arguments.

5.3  Passing extra options to view functions

       URLconfs have a hook that lets you pass extra arguments to your view functions, as a Python dictionary.

The django.conf.urls.url() function can take an optional third argument which should be a dictionary of extra keyword arguments to pass to the view function.

For example:

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

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

       In this example, for a request to /blog/2005/, Django will call views.year_archive(request, year='2005',foo='bar').

This technique is used in the syndication framework to pass metadata and options to views.

Dealing with conflicts

       It’s possible to have a URL pattern which captures named keyword arguments, and also passes arguments with the same names in its dictionary of extra arguments. When this happens, the arguments in the dictionary will be used instead of the arguments captured in the URL.

5.4 name param

图片 66图片 67

urlpatterns = [
    url(r'^index',views.index,name='bieming'),
    url(r'^admin/', admin.site.urls),
    # 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),

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

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 'bieming' %}" method="post">
         用户名:<input type="text" name="username">
         密码:<input type="password" name="password">
         <input type="submit" value="submit">
     </form>
</body>
</html>


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

View Code

5.5 Including other URLconfs

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

六 Django Views(视图函数)

图片 68

http央求中发生七个大旨指标:

        http请求:HttpRequest对象

        http响应:HttpResponse对象

所在地点:django.http

在此以前大家用到的参数request便是HttpRequest    检验方法:isinstance(request,HttpRequest)

本文由金沙澳门官网发布于网络编程,转载请注明出处:一周后的重温

关键词: 金沙澳门官网

上一篇:没有了
下一篇:没有了