Django基础

Posted Z贺

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django基础相关的知识,希望对你有一定的参考价值。

知识预览

 

ORM性能相关
        user_list = models.UserInfo.objects.all()
            for row in user_list:
                # 只去取当前表数据 如果增加了外键,没查一次外键,就会查询一次数据库
    
        select_related,主动连表查询【FK】
            
            user_list = models.UserInfo.objects.all().select_related(\'FK字段\')
            for row in user_list:
                # 只去取当前表数据和FK表关联字段 查询其他字段,查询一次访问一次数据库
        
        
            user_list = models.UserInfo.objects.values(...)
            for row in user_list:
                # 只去取当前表数据和FK表关联字段
        
            ==》 连表降低性能
    
        prefetch_related
            user_list = models.UserInfo.objects.all().prefetch_related(\'FK字段\')
    
            # [obj,obj,obj]
            # 查询用户表models.UserInfo.objects.all() 1000
            # 把用户表中所有的ut_id拿到, 用户类型ID [1,2,3]
            # 把用户表中所有的ut_id拿到, 用户类型ID [21,21,31]
            # select * from UsetType where id in [1,2,3]
            # select * from xx where id in [21,21,31]
            user_list = models.UserInfo.objects.all().prefetch_related(\'ut\',\'xx\')
            for row in user_list:
                print(row.name, row.pwd, row.ut.caption)
        补充:
            # [obj,obj,obj]
            # user_list = models.UserInfo.objects.all().only(\'name\')   # 只取某个字段 select name from userinfo 
            # user_list = models.UserInfo.objects.all().defer(\'name\')  # 排除当前字段    
            # for row in user_list:
            #     print(row.pwd)

 

Django: 大而全

Flask : 小而精


Django基本命令

1  django-admin  startproject project_name     创建项目
2  python manage.py startapp  appName          创建应用
3  python manage.py runserver IP PORT          启动项目

4 python manage.py makemigrations 创建数据库 5 python manage.py migrate 创建数据库


6 python manage.py flush  清空数据库



MTV  C

M:model
T:template
V: views
C: Controller(路由分配系统)


一 路由分配系统

    功能:客户端访问的url的路径(path)与视图函数一一映射关系
    语法格式:
  
    urlpatterns = [
          url(正则表达式, views视图函数,参数,别名),
    ]
            
    key:    通过路径分组传参数给视图函数
    
    无名分组:url(r\'^(\\d{4})/$\', year_query),           #    year_query(request,2007)
            
    有名分组:url(r\'^(?P<year>\\d{4})/(?P<month>\\d{2})$\', year_query),          #    year_query(request,year=2010,month=12)

    name参数:    url(r\'^regq/\', reg,name="register"),  #<form action="{% url \'INDEX\' %}" method="post">  等同于 <form action="/index/" method="post">     

   路由分流: urlpatterns = [
       url(r\'^admin/\', admin.site.urls),
    url(r\'^blog/\', include(\'[App名].urls\')),
    url(r\'^blog/\', include(\'blog.urls\')),
]

二 视图函数(views)

    请求对象: request
    响应对象: httpresponse("")
    
    request.method   : 请求方式
    request.GET    : 存放 get请求数据
    request.POST   : 存放 post数据
    #用原数据 queryset 后面处理多选列表的时候 get 只能取到列表最后一个值,getlist 得到所有值
    
    Httpresponse("[html 字符串]")             ------>实例字符创对象
    render(request,"[HTML 文件]",local())     ------>模板的渲染
    redirect("[HTML 链接 (/book/index/)]")   ------>跳转(最前面没有 / 好像默认从当前 app 补充前段的链接,如 index/ 相当于 /book/index/)

三 模板语言
    模板语言: 渲染变量 {{}}         渲染标签 {% %}
    
    目的: 将变量嵌入到html中
    
           注意:
               1 只要带有模板语法的html都成为模板    

               2 render方法渲染时 把后端变量嵌入到模板中               
    
    
             关于redirect与render的区别:
                redirect走的是路径
                render返回的是模板
    万能的句点号(.):

        列表索引 、
        字典key|value 或者 某一key 、
        对象属性 、
        对象的方法(如 .upper .isdigit 只能调用不传参的方法)

   显示处理(filter) {{ obj | filter:param }}

   {% if %} {% for %} forloop ……

   自定义 filter simple_tag

        {{ num|filter:[参]}}    

         可以用在 for 、 if 中但是只能有一个参数,但是这个参数可以通过 列表、元组 等方式存放多个参数的。

        {% simple_tag [参] [参] [参] %} 参数不限,但不能放在if for语句中

    

     extend模板继承

        模板:{% load staticfiles %}   {% block [block 名字] %}{% endblock %}

        继承:{% extends "[模板 HTML 文件]" %}  {% block [block 名字] %}{% endblock %}

四 ORM
 
四 ORM

0 配置数据库(mysql):settings 、 __init__ 、 migrate
1 添加方法 表.objects.create() obj=类(title="") obj.save() 外键字段添加方式(一对多) Book.objects.create(title="",price="",publish_id=) # publish_id对应的Publish表中的主键id Book.objects.create(title="",price="",publish=pub_obj) # publish_id对应的Publish表中的主键id book_obj.publish : 与这本书相关联的出版社对象(一个) 外键字段添加方式(多对多) authors=models.ManyToManyFields("Author") book_obj.authors : 与这本书相关的所有的作者集合(querySet) book_obj.authors.add(obj1,obj2) book_obj.authors.add(*[]) book_obj.authors.remove(obj) book_obj.authors.clear() 2 查询方法 表.objects.all() -----------QuerySet [obj,obj] 表.objects.filter(id__gt=3,id__lt=6) -----------QuerySet [obj,obj] 表.objects.get() -----------model对象 QuerSet.first() -----------model对象 QuerSet.last() -----------model对象 eg: 表.objects.all().first() 表.objects.values(字段) --------- 存放字典的集合对象,也可以当做sql语句中的 group by 分组使用 <QuerySet [{\'price\': Decimal(\'45.00\'), \'title\': \'linux\'}, {\'price\': Decimal(\'100.00\'), \'title\': \'老男孩历险记\'}, {\'price\': Decimal(\'12.00\'), \'title\': \'老男孩感情史\'}]>

QuerySet的高效使用:
1 可切片 2 可迭代 3 惰性机制 iterator ----------阅后即焚 exits ----------是否存在 连表查询 (了不起的下划线) class Book_authors(): book_id=... author_id=.... class Author(): name=..... #books=models.ManyToManyFields("Book") class Publish(): name=.... class BOOK(): title=... publish=... authors=..... 1 基于对象 正向查询:(多对多的时候,ManyToManyField 在哪个表那个表是正向查询) # 查询某本书的出版社或者作者信息 book_obj=BOOK.objects.get(id=4) book_obj.publish # 与这本书相关联的出版社 book_obj.authors # 与这本书关联的作者对象集合 反向查询: # 查询某个出版社出版过的书 # 查询某个作者出版社过的书 author_obj=Author.objects.get(id=2) author_obj.关联表名__set author_obj.book__set # 与这个作者关联的所有书籍对象的集合 2 基于 filter values __ 表.objects.filter().values() # 查询python这本书的出版社名字 BOOK.objects.filter(title="python").values(publish__name) Publish.objects.filter(book__title="python").values("name") 聚合与分组 在sql: select max() group by 字段 having select Avg(score) from stu aggreagte: Book.objects.all().aggregate(AvgPrice=Avg("price")) annotate: # 每一个作者出版过的书中的最高价 : 按作者名字分组 ret4=Book.objects.values("authors__name").annotate(Max("price")) print(ret4) F Q F: Book.objects.all().update(price=F("price")+20) Q: Book.objects.filter(Q(price__gt=200) | Q(id__gt=5) ,title__startswith="") 3 修改方法 Book.objects.filter(id=5).update(price=1000) 4 删除 Book.objects.filter(id=5).delete() # 级联删除 Ajax(******): json对象 就是js对象子集 (number string(“”) bool array null {“”:“”}) json字符串

 

from django.shortcuts import render,HttpResponse


from app01.models import *
# Create your views here.


def add(request):

    # 添加记录两种方式:
    # create 方式

    # Publish.objects.create(
    #     name="老衲出版社",
    #     addr="沙河"
    #
    # )
    #
    # # save方式
    #
    # p=Publish(name="瞎驴出版社",addr="昌平区")
    # p.save()

 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


    # 一对多 添加一个book记录 方法1 :

    # Book.objects.create(
    #     title="python",
    #     price=100.00,
    #     publish_id=2
    # )



    # book_obj=Book.objects.get(id=1)
    # print(book_obj.title)
    # print(book_obj.price)
    # print(book_obj.publish)


    # 一对多 create 方法 添加一个book记录 方法2:
    #publish_obj=Publish.objects.get(id=1)    #  一个北京出版社对象

    # 创建一个Book对象
    #
    # Book.objects.create(
    #     title="Linux",
    #     price=29.00,
    #     publish=publish_obj
    # )

    # 一对多 save 方法

    # b=Book(title="",price="",publish=pub_obj)
    # b.save()
    #
    # b = Book(title="", price="", publish_id=1)
    # b.save()

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# 添加多对多关系

# +++++++++++++++++++通过对象绑定关系

    #book_obj=Book.objects.get(id=3)

    #print("authors:  ",book_obj.authors.all()) # id=3的这本书所有关联的作者对象集合 [author1,author2,]

    # author_obj1=Author.objects.get(id=1)
    # author_obj2=Author.objects.get(id=2)

    #author_list=Author.objects.all()

    # 绑定关系
    # 正向绑定

    # book_obj.authors.add(author_obj1,author_obj2)
    #book_obj.authors.add(*author_list)

    author_obj=Author.objects.get(name="Yuan")

    author_obj.book_set.add(*Book.objects.all())



    # 解除绑定

    #book_obj.authors.clear()

    #author=Author.objects.get(name=\'alex\')

    #book_obj.authors.remove(author)
    #book_obj.delete()



    # 向手动创建的第三张表中添加记录

    # b2a=Book2Author(book_id=4,author_id=3)
    # b2a.save()


    return HttpResponse("OK")



def query(request):

    # 双下划线 __

    # publish_list=Publish.objects.filter(id__gt=1)
    #
    # print(publish_list)


    book_list=Book.objects.filter(title__contains="老男孩")
    print(book_list)


    return HttpResponse("OK")

def query2(request):

    #++++++++++++++++++++++++++++ values 显示方法
    #ret=Book.objects.all().values("price","title")
    #print(ret)
# <QuerySet [{\'title\': \'linux\'"}, {\'title\': \'老男孩历险记\'}, {\'title\': \'老男孩感情史\'}]>

    # 所有id大于1 的书籍的title
    # ret=Book.objects.filter(id__gt=1).values("title")
    # ret=Book.objects.filter(id__gt=1).values_list("title")
    # print(ret)# <QuerySet [(\'linux\',), (\'老男孩历险记\',), (\'老男孩感情史\',)]>


 #+++++++++++++++++++++++++++++++++++

    #  按条件排除

    # ret=Book.objects.exclude(id__gt=4)
    # ret=Book.objects.exclude(title__contains="li")
    # print(ret)  # <QuerySet [<Book: linux>]>


    # 反转 reverse order by

    ret=Book.objects.filter(id__gt=2).order_by("price").reverse()
    print(ret)


    return HttpResponse("OK")



def queryset(request):

    #  Queryset集合支持切片操作
    #ret=Book.objects.all()[2]
    #ret=Book.objects.all()[0:2]
    #ret=Book.objects.all()[::2]
    #print(ret)


    #book_list=Book.objects.all().iterator()
    book_list=Book.objects.all()

    if book_list.exists():
        print("PK")


    # if book_list:
    #     print("Ok")

    # for obj  in book_list:
    #     print(obj.title,obj.price)
    #
    # #Book.objects.filter(title="linux").update(price=145)
    #
    # for obj  in book_list:
    #     print(obj.title,obj.price)

    return HttpResponse("OK")

def  relationQuery(request):

    ######################################借助对象以及属性publish,authors

    # # 查询linux这本书的出版社的地址
    #
    # book_obj=Book.objects.filter(title="linux").first()
    #
    # print(book_obj.publish.addr) # 北京
    # # sql: 子查询:select  * from publish where id=(select publish_id from Book where title=\'linux\')
    # #join: select publish.addr from book left join publish on book.publish_id=publish.id where title="linux"
    #
    # # 查询 老男孩感情史这本书的所有作者
    #
    # book_obj=Book.objects.filter(title="老男孩感情史").first()
    # authors_list=book_obj.authors.all()
    # for obj in authors_list:
    #     print(obj.name)
    #
    #
    #
    # # 反向 : 查询人民出版社出版过哪些书
    #
    # # 方式1
    # pub=Publish.objects.get(name="人民出版社")
    # book_list=pub.book_set.all()
    # print(book_list)
    #
    # # <QuerySet [<Book: linux>, <Book: 水浒传>]>
    #
    # # 方式2
    # pid=Publish.objects.get(name="人民出版社").id
    #
    # book_list=Book.objects.filter(publish_id=pid)
    #
    # print(book_list)  # <QuerySet [<Book: linux>, <Book: 水浒传>]>




    ##########################value filter : 双下划线__#############

    # ret=Book.objects.filter(title="linux").values("price")
    # print(ret) #<QuerySet [{\'price\': Decimal(\'145.00\')}]>
    #
    # # 查询linux这本书的出版社的地址
    #
    # ret=Book.objects.filter(title="linux").values("publish__name")
    # print(ret)
    #
    #
    # ret=Publish.objects.filter(book__title="linux").values("name")
    # print(ret)
    #
    # #查询 老男孩感情史这本书的所有作者
    # # ret=Book.objects.filter(title="老男孩感情史").values("authors__name")
    # # print(ret)

    # 查询价格大于100的书籍的作者姓名

    # ret=Book.objects.filter(price__gt=100).values("authors__name")
    # print(ret)

    # ret=Author.objects.filter(book__price__gt=100).values("name")
    # print(ret)
    #<QuerySet [{\'name\': \'oldmen\'}, {\'name\': \'Yuan\'}]>



    return HttpResponse("OK")


def aggreAnno(request):

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

    # 求所有书籍的平均价格

    ret=Book.objects.all().aggregate(AvgPrice=Avg("price"))

    print(ret) # {\'AvgPrice\': 73.8}

    #求所有书籍的最高价格

    ret2 = Book.objects.all().aggregate(MaxPrice=Max("price"))
    print(ret2) # {\'MaxPrice\': Decimal(\'145.00\')}

    # 老男孩出版过的过的书中的最高价

    ret3=Book.objects.filter(authors__name="oldmen").aggregate(Max("price"))
    print(ret3)

    # 每一个作者出版过的书中的最高价 : 按作者名字分组

    ret4=Book.objects.values("authors__name").annotate(Max("price"))
    print(ret4)

    #<QuerySet [{\'authors__name\': \'egon\', \'price__max\': Decimal(\'45.00\')}, {\'authors__name\': \'alex\', \'price__max\': Decimal(\'12.00\')}, {\'authors__name\': \'wupeiqi\', \'price__max\': Decimal(\'67.00\')}, {\'authors__name\': \'oldmen\', \'price__max\': Decimal(\'145.00\')}, {\'authors__name\': \'Yuan\', \'price__max\': Decimal(\'145.00\')}]>

    #  每一个出版社出版过的书中最低价格

    Book.objects.values("publish__name").annotate(Min("price"))

    return HttpResponse("OK")


def FAndQ(request):
    from django.db.models import F,Q

    #Book.objects.all().update(price=F("price")+20)

    # 查询

    # ret=Book.objects.filter(title__startswith="老",price__gt=100)
    # print(ret) # <QuerySet [<Book: 老男孩历险记>]>


    # Q查询支持的逻辑运算符:  & | ~

    # ret2 = Book.objects.filter(Q(title__startswith="老") | Q(price__gt=200),)
    # print(ret2)  #<QuerySet [<Book: linux>, <Book: 老男孩历险记>, <Book: 老男孩感情史>]>

    ret3 = Book.objects.filter(Q(price__gt=200) | Q(id__gt=5) ,title__startswith="")
    print(ret3) #<QuerySet [<Book: 老男孩历险记>, <Book: 老男孩感情史>]>


    return HttpResponse("OK")



def edit(req):

    #修改方式1 (推荐)
    #Book.objects.filter(id=5).update(price=1000)  #  update是QuertySet集合对象的方法

    #修改方式2  (效率低)   对象信息更改后,可以用save()来保存更改,但是会更新所有信息,效率低于update

    book=Book.objects.get(id=5)

    # book.price=400
    # book.save()

    return HttpResponse("OK")
讲课记录,一点补充

 

 

一 什么是web框架?

  • #框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,#使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演。
    
    #对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。
    
    
    
    
    
    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()
    
    
    
    
    #      最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。
    
    #如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。
    
    #      正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。
    
    #      这个接口就是WSGI:Web Server Gateway Interface。
    View Code

-----------------------------Do a web  framework ourselves---------------------------