zoukankan      html  css  js  c++  java
  • django目前所用整理

    git:https://gitee.com/momomoyu/django-js-html

    分页器

    分页器是基于form提交的,与ajax很难形成动态局部刷新(以目前的水平以及调研程度来讲)

    后面更换为了基于handlebar.js和pagination.js的动态局部刷新

    关于封包如何存储与static中,可在其中下载得到。

    其中handlebars在linux环境下,其内的div设置的flow及col的属性存在冲突,还在纠正问题所在。

    models的使用

    在本帖中可以看到

    https://www.cnblogs.com/threeidiots/articles/14139306.html

    简介
    查询集表示从数据库中获取的对象集合
    查询集可以含有零个、一个或多个过滤器
    过滤器基于所给的参数限制查询的结果
    从Sql的角度,查询集和select语句等价,过滤器像where和limit子句
    接下来主要讨论如下知识点
    查询集
    字段查询:比较运算符,F对象,Q对象
    查询集
    在管理器上调用过滤器方法会返回查询集
    查询集经过过滤器筛选后返回新的查询集,因此可以写成链式过滤
    惰性执行:创建查询集不会带来任何数据库的访问,直到调用数据时,才会访问数据库
    返回查询集的方法,称为过滤器
    all()
    filter()
    exclude()
    order_by()
    values():一个对象构成一个字典,然后构成一个列表返回
    写法:
    filter(键1=值1,键2=值2)
    等价于
    filter(键1=值1).filter(键2=值2)
    返回单个值的方法
    get():返回单个满足条件的对象
    如果未找到会引发"模型类.DoesNotExist"异常
    如果多条被返回,会引发"模型类.MultipleObjectsReturned"异常
    count():返回当前查询的总条数
    first():返回第一个对象
    last():返回最后一个对象
    exists():判断查询集中是否有数据,如果有则返回True
    限制查询集
    查询集返回列表,可以使用下标的方式进行限制,等同于sql中的limit和offset子句
    注意:不支持负数索引
    使用下标后返回一个新的查询集,不会立即执行查询
    如果获取一个对象,直接使用[0],等同于[0:1].get(),但是如果没有数据,[0]引发IndexError异常,[0:1].get()引发DoesNotExist异常
    查询集的缓存
    每个查询集都包含一个缓存来最小化对数据库的访问
    在新建的查询集中,缓存为空,首次对查询集求值时,会发生数据库查询,django会将查询的结果存在查询集的缓存中,并返回请求的结果,接下来对查询集求值将重用缓存的结果
    情况一:这构成了两个查询集,无法重用缓存,每次查询都会与数据库进行一次交互,增加了数据库的负载
    print([e.title for e in Entry.objects.all()])
    print([e.title for e in Entry.objects.all()])
    情况二:两次循环使用同一个查询集,第二次使用缓存中的数据
    querylist=Entry.objects.all()
    print([e.title for e in querylist])
    print([e.title for e in querylist])
    何时查询集不会被缓存:当只对查询集的部分进行求值时会检查缓存,但是如果这部分不在缓存中,那么接下来查询返回的记录将不会被缓存,这意味着使用索引来限制查询集将不会填充缓存,如果这部分数据已经被缓存,则直接使用缓存中的数据
    字段查询
    实现where子名,作为方法filter()、exclude()、get()的参数
    语法:属性名称__比较运算符=值
    表示两个下划线,左侧是属性名称,右侧是比较类型
    对于外键,使用“属性名_id”表示外键的原始值
    转义:like语句中使用了%与,匹配数据中的%与,在过滤器中直接写,例如:filter(title__contains="%")=>where title like ‘%%%’,表示查找标题中包含%的
    比较运算符

    exact:表示判等,大小写敏感;如果没有写“ 比较运算符”,表示判等
    filter(isDelete=False)
    contains:是否包含,大小写敏感
    exclude(btitle__contains=‘传’)
    startswith、endswith:以value开头或结尾,大小写敏感
    exclude(btitle__endswith=‘传’)
    isnull、isnotnull:是否为null
    filter(btitle__isnull=False)
    在前面加个i表示不区分大小写,如iexact、icontains、istarswith、iendswith
    in:是否包含在范围内
    filter(pk__in=[1, 2, 3, 4, 5])
    gt、gte、lt、lte:大于、大于等于、小于、小于等于
    filter(id__gt=3)
    year、month、day、week_day、hour、minute、second:对日期间类型的属性进行运算
    filter(bpub_date__year=1980)
    filter(bpub_date__gt=date(1980, 12, 31))
    跨关联关系的查询:处理join查询
    语法:模型类名 <属性名> <比较>
    注:可以没有__<比较>部分,表示等于,结果同inner join
    可返向使用,即在关联的两个模型中都可以使用
    filter(heroinfo_ hcontent contains=‘八’)
    查询的快捷方式:pk,pk表示primary key,默认的主键是id
    filter(pk__lt=6)
    聚合函数
    使用aggregate()函数返回聚合函数的值
    函数:Avg,Count,Max,Min,Sum
    from django.db.models import Max
    maxDate = list.aggregate(Max(‘bpub_date’))
    count的一般用法:
    count = list.count()
    F对象
    可以使用模型的字段A与字段B进行比较,如果A写在了等号的左边,则B出现在等号的右边,需要通过F对象构造
    list.filter(bread__gte=F(‘bcommet’))
    django支持对F()对象使用算数运算
    list.filter(bread__gte=F(‘bcommet’) * 2)
    F()对象中还可以写作“模型类__列名”进行关联查询
    list.filter(isDelete=F(‘heroinfo__isDelete’))
    对于date/time字段,可与timedelta()进行运算
    list.filter(bpub_date__lt=F(‘bpub_date’) + timedelta(days=1))
    Q对象
    过滤器的方法中关键字参数查询,会合并为And进行
    需要进行or查询,使用Q()对象
    Q对象(django.db.models.Q)用于封装一组关键字参数,这些关键字参数与“比较运算符”中的相同
    from django.db.models import Q
    list.filter(Q(pk lt=6))
    Q对象可以使用&(and)、|(or)操作符组合起来
    当操作符应用在两个Q对象时,会产生一个新的Q对象
    list.filter(pk lt=6).filter(bcommet gt=10)
    list.filter(Q(pk lt=6) | Q(bcommet _gt=10))
    使用~(not)操作符在Q对象前表示取反
    list.filter(~Q(pk__lt=6))
    可以使用&|~结合括号进行分组,构造做生意复杂的Q对象
    过滤器函数可以传递一个或多个Q对象作为位置参数,如果有多个Q对象,这些参数的逻辑为and
    过滤器函数可以混合使用Q对象和关键字参数,所有参数都将and在一起,Q对象必须位于关键字参数的前面

    转载自传智播客

    关键在于惰性查询和缓存部分,这部分没有多余的佐证,目前的理解就是在当前函数内,存在第二次缓存。退出函数之后缓存失效。其余部分可作为工具书参考。

    queryset整理

    特性:可迭代,可切片,惰性,缓存

    queryset为models查询出的结果集,最外侧是列表,每一条都是一个字典,携带表名,pk(id)以及fields(其他属性)等,fields里面承载的数据。

    在创建时不会进行查询操作,只有在使用过滤器时会触发查询,然后缓存。缓存机制在models中有所论述。

    queryset虽然可以通过for循环进行遍历,但是其每一条并不等同于字典,直接通过[]进行访问会报迭代错误。其每一条可通过.进行访问,

    T = NightResult.objects.all()[:1] 
    print(T[0].result)
    for i in T:
       i.id
    

    queryset可以切片查询,但是不支持负索引,切片查询时会只查询指定范围。

    另外queryset可以更新单条,但是与update不同,update会直接递交数据库,但是对于queryset而言,不主动递交,是不会将本地的修改递交到数据库的。

    twz = Author.objects.get(name="WeizhongTu")
    twz.name="WeizhongTu"
    twz.email="tuweizhong@163.com"
    twz.save()  # 最后不要忘了保存!!!
    

    queryset创建对象的方法

    #总之,一共有四种方法
    # 方法 1
    Author.objects.create(name="WeizhongTu", email="tuweizhong@163.com")
     
    # 方法 2
    twz = Author(name="WeizhongTu", email="tuweizhong@163.com")
    twz.save()
     
    # 方法 3
    twz = Author()
    twz.name="WeizhongTu"
    twz.email="tuweizhong@163.com"
    twz.save()
     
    # 方法 4,首先尝试获取,不存在就创建,可以防止重复
    Author.objects.get_or_create(name="WeizhongTu", email="tuweizhong@163.com")
    # 返回值(object, True/False)
    

    前三种返回object,最后一种多返回一个bool值。

    .distinct()可进行去重,在查询列名时可以使用,联表查询时也可以使用

     queryset对于惰性的解释:

    官方文档

    概括:

    query在被构造,切片等操作时不会对数据库操作, 这里就是queryset惰性, 也叫惰性查询,也就是说单纯的创建queryset

    那么, 什么操作会使queryset进行数据库活动呢:

    迭代(Iteration), for i in queryset
    切片(Slicing), 带有步长的切片, queryset[::2]
    索引, queryset[0]
    序列化/缓存化(Pickling/Caching), 将数据保存到redis中或者内存中的时候
    repr(). 直接打印, print(queryset)
    len(). len(queryset)
    list(). list(queryset)
    bool(). queryset if queryset else None
    queryset关于缓存的机制

    每个查询集都包含一个缓存来最小化对数据库的访问。理解它是如何工作的将让你编写最高效的代码。

    在一个新建的查询集中,缓存为空,首次对查询集求值,会发生数据库查询,django会将查询的结果保存到缓存中并返回明确的请求结果,接下来的求值将复用缓存的结果。

    对查询集使用不当的话,它会浪费系统资源。例如,下面的语句创建两个查询集,对它们求值,然后扔掉它们:

    print([a.title for a in models.Article.objects.all()])
    print([a.create_time for a in models.Article.objects.all()])
    

    如此,相同的查询会被调用两次,致使数据库负载增大,但是这个地方还是有一定疑问的,它是如何保证查询集的最新状态呢?

    何时查询集不会被缓存?

    查询集不会永远缓存他们的结果,当只对查询集的部分进行求值时会检查缓存,如果这个部分不在缓存中,name接下来查询返回的结果都不会被缓存,所以,切片或索引来限制查询集将不会填充缓存。

    例如,重复获取查询集对象中一个特定的索引将每次都查询数据库

    >>> queryset = Entry.objects.all()
    >>> print queryset[5] # Queries the database
    >>> print queryset[5] # Queries the database again
    

    然而,如果已经对全部查询集求值过,则将检查缓存:

    >>> queryset = Entry.objects.all()
    >>> [entry for entry in queryset] # Queries the database
    >>> print queryset[5] # Uses cache
    >>> print queryset[5] # Uses cache
    

    下面的一些其他栗子,他们会是的全部的查询集被求值并填充到缓存:

    >>> [entry for entry in queryset]
    >>> bool(queryset)
    >>> entry in queryset
    >>> list(queryset)
    

    简单的打印查询集不会填充缓存。

    exists()与iterator()方法:

    简单的使用if语句进行判断也会执行查询并将整个数据放入cache,虽然我们并不需要这些数据,为防止这种情况,可以用exists()来检查是否有数据:

     if queryResult.exists():
        #SELECT (1) AS "a" FROM "blog_article" LIMIT 1; args=()
            print("exists...")
    

    而iterator可以在查询集太大时,不保留缓存,因为太大的数据存入缓存是不够高效的,巨大的数据量进行缓存可能锁住系统进程,让程序濒临崩溃,为避免在遍历数据时产生queryset cache,可以使用iterator()来获取数据,处理完数据后将其丢弃。

    objs = Book.objects.all().iterator()
    # iterator()可以一次只从数据库获取少量数据,这样可以节省内存
    for obj in objs:
        print(obj.title)
    #BUT,再次遍历没有打印,因为迭代器已经在上一次遍历(next)到最后一次了,没得遍历了
    for obj in objs:
        print(obj.title)
    

    iterator的使用环境是为了防止生成cache,同时会产生遍历同一个queryset是会重复执行查询的问题,所以使用之前需要确保在操作一个大的queryset是没有执行重复查询。

    总结:

    queryset的cache可以用于减少程序对数据库的查询,通常使用下会保证只有在需要的时候才会查询数据库,使用exists和iterator方法时可以优化程序对内存的使用,但是可能会造成额外的数据库查询,

  • 相关阅读:
    .Net下的MSMQ(微软消息队列)的同步异步调用
    [收藏]JS获取网页中HTML元素的几种方法分析
    在FireFox下设为首页的解决方法
    如何创建和使用Web Service代理类
    [收藏]61条面向对象设计的经验原则
    [总结]DotNet中用到的加密算法总结
    如何把用SQL语句int型整数转换成二进制数
    彻底杜绝PHP的session,cookie,Cannot modify header错误
    MSN总是报80048820的错误,网上搜的一些资料解决不了,我找到了真正解决办法!
    [收藏]MD5加密的javascript实现
  • 原文地址:https://www.cnblogs.com/threeidiots/p/14620140.html
Copyright © 2011-2022 走看看