• Django数据模型及操作


    转自:http://blog.sina.com.cn/s/blog_a73687bc0101cygy.html

    (一) 初始化测试运行环境

    import os;

    import sys;

    sys.path.append("G:/pydev/mysite2")   # 需要修改

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")   # 需要修改

    from qi.models import *

    Catalog.objects.all()

    Catalog.objects

    其中Catalog.objects是django.db.models.manager.Manager类型的对对象,Manager是模型(Model)访问数据的操作接口。

    扩展

    可以为数据模型定义自己的"manager",具体参考:

    https://docs.djangoproject.com/en/1.5/topics/db/managers/#django.db.models.Manager

    技巧

    import os;

    import sys;

    sys.path.append("G:/pydev/mysite2")   # 需要修改

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")   # 需要修改

    可以放到 Python27Libsite-packagessitecustomize.py 文件中这样可以不用每次都输

    由于目前尚无法解决命令行的字符集设置问题,所有以下的例子都是在程序文件中编写并执行。

    在mysite2/qi(应用程序目录)目录下新建mytest.py,编写代码,并在eclipse下执行。

    (一)创建对象

    Catalog(name="测试",code="test").save();

    (二)使用get读取对象

    print(Catalog.objects.get(id=1));

    print(Catalog.objects.get(name="根目录"));

    print(Catalog.objects.get(id=1, name="根目录" , state='A'));

    使用get获取对象的时候如何,如果对象不存在或符合条件的对象超过1个,都将出现异常。

    (三)使用filter和exclude

    print(Catalog.objects.filter(code__startswith="c", state="A"));

    print(Catalog.objects.filter(code__startswith="c", state="A").filter(id = 42));

    print(Catalog.objects.filter(code__startswith="c", state="A").exclude(id = 42));

    print(Catalog.objects.filter(code__icontains="er"))   # 包含

    print(Catalog.objects.filter(code__icontains="i"))   # 包含

    其中"__"表示"."的作用,这个由django来转义。

    使用filter可以允许没有返回数据,或者多个返回数据。

    filter和exclude可以串联使用

    (四) 简单日期操作

    from datetime import datetime;

    from datetime import date;

    print(Catalog.objects.filter(create_date__year=2013));   # 时间的年份为2013年

    print(Catalog.objects.filter(create_date__gte=date.today()));   # 时间大于今天

    print(Catalog.objects.filter(create_date__gte=datetime(2013, 5, 23))); # 时间大于2013年5月23日

    print(Catalog.objects.filter(create_date__lte='2013-05-23'))  # 时间小于2013年5月23日

    (五)exists使用

    print(Catalog.objects.filter(pk=1).exists())

    (六) 用索引器限制记录的数量

    print(Catalog.objects.all())

    print(Catalog.objects.all()[:5])

    print(Catalog.objects.all()[0:5])

    print(Catalog.objects.all()[3:5])

    print(Catalog.objects.all()[1:6:2])

    print(Catalog.objects.order_by('ord')[0])   # 没有找到数据会报异常:IndexError: list index out of range

    print(Catalog.objects.order_by('ord')[0:1])   # 注意该方法和上1行,一样是取第1条记录,但是如果没有找到数据,这样写法不会报异常

    print(Catalog.objects.order_by('-ord')[0])   # 倒序排序,取最后一个

    (七)exact和iexact使用

    print(Catalog.objects.filter(code__exact="public")); 

    print(Catalog.objects.filter(code__iexact="PUBLIC"));  # 大小写不敏感

    print(Catalog.objects.filter(code__exact="PUBLIC"));   # 查无数据

    默认情况下执行的是写code="public"等价于code__exact="public"。

    (八)contains和icontains

    print(Catalog.objects.filter(code__contains="er"));

    print(Catalog.objects.filter(code__icontains="ER")); # 大小写不敏感

    print(Catalog.objects.filter(code__contains="ER")); # 查无数据

    code__contains="er"相当于SELECT ... from qi_catalog WHERE code LIKE '%er%';


    (九)startswith和endswith

    print(Catalog.objects.filter(code__startswith="c"));

    print(Catalog.objects.filter(code__endswith="e"));

    print(Catalog.objects.filter(code__istartswith="C")); # 大小写不敏感

    print(Catalog.objects.filter(code__iendswith="E"));   # 大小写不敏感

    (十)一对多对象的访问

    print(Catalog.objects.filter(parent__name="根目录")) # parent = models.ForeignKey('self'); # 访问根目录下的所有子目录

    (十一)多对对关系

    class Catalog(StateObject)

    ... ...

    papers = models.ManyToManyField(Paper, through='CatalogPaper')

    ... ...

    print(Catalog.objects.filter(papers__name__startswith="公益"))  # 通过papers变量访问

    print(Catalog.objects.filter(catalogpaper__paper__name__startswith="公益"));

    # 通过隐含的多对多关系,以上方式特别注意Catalog没有catalogpaper字段,这是通过隐含多对多关系访问同样的方法也可以用paper对象来访问catalog,如下:

    print(Paper.objects.filter(catalogpaper__catalog__name="公益"))

    这种方式访问关联对象进行条件组合要注意,串联filter或exclude是,和直接使用(,..,..)表达是有语义不同的,请注意一下两种写法,是不同的:

    print(Catalog.objects.filter(catalogpaper__paper__name="公益问卷1" , catalogpaper__paper__name__startswith='公益问卷2'))  # 不会用数据返回,因为不可能有一个目录下包含一个问卷名字叫做"公益问卷1"且同时名字又以“公益问卷2”开头的。

    print(Catalog.objects.filter(catalogpaper__paper__name="公益问卷1").filter(catalogpaper__paper__name='公益问卷2')) # 有可能查到数据,此语义为找一个目录,其下既有一个名为“公益问卷1”的问卷,又有一个以“公益问卷2”开头的问卷(实际上是两个问卷)。

    # 通过xxxx_set访问多对多关系

    c = Catalog.objects.get(id=41);

    cp = c.catalogpaper_set.all();

    for p in cp :

    print(p.paper.name)

    注意:django中的带扩展属性的多对多关系,实际上是用一对多的关系实现的,所以我们实际上也可以用这种方法访问多对多关系

    (十二)isnull使用

    print(Catalog.objects.filter(parent__isnull=True))

    未完待续

    (十三)使用F()

    可以使用F()来在等号右边引用对象查询中的字段,但是此时似乎不能用使用startswith,contains等关联词,但是可以用__lt,__lte,__gt,__gte等。

    from django.db.models import F;

    print(Catalog.objects.filter(name=F('name')))

    思考:这里在等号的右边不能使用“xx__xxx__xxx”这样的方式来表示对象的对应属性,应为在等号左边python当成是局部变量的定义,所以怎么写都没有关系。是如果在等号右边,要嘛是一个已定义变量,要嘛是一个数值或字符串。当然也不能使用字符串来表示对象的属性,因为会于字符串作为比较表达式的情况出现语言混乱,所以django才增加了一个叫做F()的类,解决这样的问题。

    print(Catalog.objects.filter(name__startswith=F('name')))  # 这个会报django.db.utils.DatabaseError: ORA-00909: invalid number of arguments。目前还不知道愿原因。

    (十四)in 的使用

    print(Catalog.objects.filter(name__in=["商业","社会"]))


    参考:https://docs.djangoproject.com/en/1.5/ref/models/querysets/#queryset-api

    (十五)字段查询关键字汇总

    exact, iexact, contains, icontains, startswith, istartswith, endswith,  iendswith

    lt(less than),gt(great than),lte(less than or equal),gte(great than or equal)

    in

    (十六)缓存机制

    # 以下语句要查询两次数据库

    print([c.code for c in Catalog.objects.all()])

    print([c.name for c in Catalog.objects.all()])

    # 以下语句可以用上django的缓存机制,只用访问一次数据

    cl = Catalog.objects.all();

    print([c.code for c in cl])

    print([c.name for c in cl])

    # 在对象查询集中使用数据索引要格外小心,因为每次索引都会访问1次数据库,即使是访问同一个元素。注意如下语句:

    cl = Catalog.objects.all();

    cl[1];  # 访问1次数据库

    cl[1];  # 在访问1次数据库

    最好是把所有数据,先遍历一边,在进行访问:

    cl = Catalog.objects.all();

    [c.code for c in cl]

    cl[1];  # 从缓存读数据

    cl[1];  # 从缓存读数据

    #  以下四种方法将对象集放进缓存

    [c for c in queryset]

    bool(queryset)

    c in queryset

    list(queryset)

    存在疑问:

    1、如何将字符串属性定义成非空null=False 和blank = False似乎都不生效

    https://docs.djangoproject.com/en/1.5/topics/db/queries/

    '''   复杂查询Q()   '''

    '''   对象比较   '''

    '''   对象删除   '''

    '''   对象拷贝   '''

    '''   一次更新多个对象   '''

    不带扩展信息的多对多关系的操作

    beatles.members.add(john)

    beatles.members.create(name="George Harrison")

    beatles.members = [john, paul, ringo, george]

    清除关系,是删除关系还是删除数据?

    beatles.members.clear()

    数据筛选

    >>> Group.objects.filter(members__name__startswith='Paul')

    []

    筛选

    # Find all the members of the Beatles that joined after 1 Jan 1961

    >>> Person.objects.filter(

    ...   group__name='The Beatles',

    ...   membership__date_joined__gt=date(1961,1,1))

    [

    筛选 : 如果  关系R=A->B   如果重复添加R'=A->B 不知会出现什么情况?

    >>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)

    >>> ringos_membership.date_joined

    datetime.date(1962, 8, 16)

    >>> ringos_membership.invite_reason

    筛选

    >>> ringos_membership = ringo.membership_set.get(group=beatles)

    >>> ringos_membership.date_joined

    datetime.date(1962, 8, 16)

    >>> ringos_membership.invite_reason

    u'Needed a new drummer.'

    直接执行sql语句

    Person.objects.raw('SELECT id, first_name, last_name, birth_date FROM myapp_person')

    参考:https://docs.djangoproject.com/en/1.5/topics/db/sql/

  • 相关阅读:
    多态
    SSM前后端分离 ssm+html+js(ajax) 这种controll层的返回值是结合或者网址
    Eclipse创建ssm项目
    在idea中创建Maven项目
    Maven的安装和配置
    IDEA修改快捷键!和一些常用的快捷键
    mysql数据库的安装和连接测试并给root用户赋密码
    ssm动态sql语句
    Java基础--JDBC
    Java基础--注解、反射
  • 原文地址:https://www.cnblogs.com/qinfengxiaoyue/p/4057082.html
Copyright © 2020-2023  润新知