`
viking2439
  • 浏览: 49019 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Django数据库queryset操作

 
阅读更多

__exact        精确等于 like 'aaa'
__iexact    精确等于 忽略大小写 ilike 'aaa'
__contains    包含 like '%aaa%'
__icontains    包含 忽略大小写 ilike '%aaa%',但是对于sqlite来说,contains的作用效果等同于icontains。
__gt    大于
__gte    大于等于
__lt    小于
__lte    小于等于
__in     存在于一个list范围内
__startswith   以...开头
__istartswith   以...开头 忽略大小写
__endswith     以...结尾
__iendswith    以...结尾,忽略大小写
__range    在...范围内
__year       日期字段的年份
__month    日期字段的月份
__day        日期字段的日
__isnull=True/False
__isnull=True 与 __exact=None的区别
class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()
    def __unicode__(self):
        return self.name
class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()
    def __unicode__(self):
        return self.name
class Entry(models.Model):
    blog = models.ForeignKey(Blog)
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateTimeField()
    authors = models.ManyToManyField(Author)
    def __unicode__(self):
        return self.headline
这 是model,有blog,author,以及entry;其中entry分别与blog与author表关 联,entry与blog表是通过 外键(models.ForeignKey())相连,属于一对多的关系,即一个entry对应多个blog,entry与author是多对多的关系, 通过modles.ManyToManyField()实现。 
一、插入数据库,用save()方法实现,如下: 
>>> from mysite.blog.models import Blog 
>>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') 
>>> b.save()
二、更新数据库,也用save()方法实现,如下: 
>> b5.name = 'New name' 
>> b5.save()

保存外键和多对多关系的字段,如下例子: 
更新外键字段和普通的字段一样,只要指定一个对象的正确类型。 
>>> cheese_blog = Blog.objects.get (name="Cheddar Talk") 
>>> entry.blog = cheese_blog 
>>> entry.save()
更新多对多字段时又一点不太一样,使用add()方法添加相关联的字段的值。 
>> joe = Author.objects.create(name="Joe") 
>> entry.authors.add(joe)
三、检索对象
>>> Blog.objects 
<django .db.models.manager.Manager object at ...> 
>>> b = Blog(name='Foo', tagline='Bar') 
>>> b.objects 
Traceback: 
    ... 
AttributeError: "Manager isn't accessible via Blog instances."
1、检索所有的对象
>>> all_entries = Entry.objects.all()
使用all()方法返回数据库中的所有对象。
2、检索特定的对象 
使用以下两个方法: 
fileter(**kwargs) 
返回一个与参数匹配的QuerySet,相当于等于(=). 
exclude(**kwargs) 
返回一个与参数不匹配的QuerySet,相当于不等于(!=)。
Entry.objects.filter (pub_date__year=2006) 
不使用Entry.objects.all().filter (pub_date__year=2006),虽然也能运行,all()最好再获取所有的对象时使用。 
上面的例子等同于的sql语句: 
slect * from entry where pub_date_year='2006'
链接过滤器: 
>>> Entry.objects.filter ( 
...     headline__startswith='What' 
... ).exclude( 
...     pub_date__gte=datetime.now() 
... ).filter ( 
...     pub_date__gte=datetime(2005, 1, 1) 
... )
最后返回的QuerySet是headline like 'What%' and put_date<now() and pub_date>2005-01-01
另外一种方法: 
>> q1 = Entry.objects.filter (headline__startswith="What") 
>> q2 = q1.exclude(pub_date__gte=datetime.now()) 
>> q3 = q1.filter (pub_date__gte=datetime.now()) 
这种方法的好处是可以对q1进行重用。
QuerySet是延迟加载 
只在使用的时候才会去访问数据库,如下: 
>>> q = Entry.objects.filter (headline__startswith="What") 
>>> q = q.filter (pub_date__lte=datetime.now()) 
>>> q = q.exclude(body_text__icontains="food") 
>>> print q 
在print q时才会访问数据库。
其他的QuerySet方法 
>>> Entry.objects.all()[:5] 
这是查找前5个entry表里的数据
>>> Entry.objects.all()[5:10] 
这是查找从第5个到第10个之间的数据。
>>> Entry.objects.all()[:10:2] 
这是查询从第0个开始到第10个,步长为2的数据。
>>> Entry.objects.order_by('headline')[0] 
这是取按headline字段排序后的第一个对象。
>>> Entry.objects.order_by('headline')[0:1].get () 
这和上面的等同的。
>>> Entry.objects.filter (pub_date__lte='2006-01-01') 
等同于SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';
>>> Entry.objects.get (headline__exact="Man bites dog") 
等同于SELECT ... WHERE headline = 'Man bites dog';
>>> Blog.objects.get (id__exact=14)  # Explicit form 
>>> Blog.objects.get (id=14)         # __exact is implied 
这两种方式是等同的,都是查找id=14的对象。
>>> Blog.objects.get (name__iexact="beatles blog") 
查找name="beatles blog"的对象,不去饭大小写。
Entry.objects.get (headline__contains='Lennon') 
等同于SELECT ... WHERE headline LIKE '%Lennon%';
startswith 等同于sql语句中的 name like 'Lennon%', 
endswith等同于sql语句中的 name like '%Lennon'.

>>> Entry.objects.filter (blog__name__exact='Beatles Blog') 
查找entry表中外键关系blog_name='Beatles Blog'的Entry对象。
>>> Blog.objects.filter (entry__headline__contains='Lennon') 
查找blog表中外键关系entry表中的headline字段中包含Lennon的blog数据。
Blog.objects.filter (entry__author__name='Lennon') 
查找blog表中外键关系entry表中的author字段中包含Lennon的blog数据。
Blog.objects.filter (entry__author__name__isnull=True) 
Blog.objects.filter (entry__author__isnull=False,entry__author__name__isnull=True) 
查询的是author_name为null的值
Blog.objects.filter (entry__headline__contains='Lennon',entry__pub_date__year=2008) 
Blog.objects.filter (entry__headline__contains='Lennon').filter (  entry__pub_date__year=2008) 
这两种查询在某些情况下是相同的,某些情况下是不同的。第一种是限制所有的blog数据的,而第二种情况则是第一个filter 是
限制blog的,而第二个filter 则是限制entry的
>>> Blog.objects.get (id__exact=14) # Explicit form 
>>> Blog.objects.get (id=14) # __exact is implied 
>>> Blog.objects.get (pk=14) # pk implies id__exact 
等同于select * from where id=14

# Get blogs entries with id 1, 4 and 7 
>>> Blog.objects.filter (pk__in=[1,4,7]) 
等同于select * from where id in{1,4,7} 
# Get all blog entries with id > 14 
>>> Blog.objects.filter (pk__gt=14) 
等同于select * from id>14
>>> Entry.objects.filter (blog__id__exact=3) # Explicit form 
>>> Entry.objects.filter (blog__id=3)        # __exact is implied 
>>> Entry.objects.filter (blog__pk=3)        # __pk implies __id__exact 
这三种情况是相同的

>>> Entry.objects.filter (headline__contains='%') 
等同于SELECT ... WHERE headline LIKE '%\%%';

Caching and QuerySets
>>> print [e.headline for e in Entry.objects.all()] 
>>> print [e.pub_date for e in Entry.objects.all()] 
应改写为: 
>> queryset = Poll.objects.all() 
>>> print [p.headline for p in queryset] # Evaluate the query set. 
>>> print [p.pub_date for p in queryset] # Re-use the cache from the evaluation.、 
这样利用缓存,减少访问数据库的次数。
四、用Q对象实现复杂的查询
Q(question__startswith='Who') | Q(question__startswith='What') 
等同于WHERE question LIKE 'Who%' OR question LIKE 'What%'

Poll.objects.get ( 
    Q(question__startswith='Who'), 
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)) 
等同于SELECT * from polls WHERE question LIKE 'Who%' AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
Poll.objects.get ( 
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)), 
    question__startswith='Who') 
等同于Poll.objects.get (question__startswith='Who', Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

五、比较对象
>>> some_entry == other_entry 
>>> some_entry.id == other_entry.id

六、删除
Entry.objects.filter (pub_date__year=2005).delete()

b = Blog.objects.get (pk=1) 
# This will delete the Blog and all of its Entry objects. 
b.delete()
Entry.objects.all().delete() 
删除所有
七、一次更新多个值
# Update all the headlines with pub_date in 2007. 
Entry.objects.filter (pub_date__year=2007).update(headline='Everything is the same')
>>> b = Blog.objects.get (pk=1) 
# Change every Entry so that it belongs to this Blog. 
>>> Entry.objects.all().update(blog=b)
如果用save()方法,必须一个一个进行保存,需要对其就行遍历,如下: 
for item in my_queryset: 
    item.save()
关联对象
one-to-many 
>>> e = Entry.objects.get (id=2) 
>>> e.blog # Returns the related Blog object.

>>> e = Entry.objects.get (id=2) 
>>> e.blog = some_blog 
>>> e.save()
>>> e = Entry.objects.get (id=2) 
>>> e.blog = None 
>>> e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"
>>> e = Entry.objects.get (id=2) 
>>> print e.blog  # Hits the database to retrieve the associated Blog. 
>>> print e.blog  # Doesn't hit the database; uses cached version.
>>> e = Entry.objects.select_related().get (id=2) 
>>> print e.blog  # Doesn't hit the database; uses cached version. 
>>> print e.blog  # Doesn't hit the database; uses cached version
>>> b = Blog.objects.get (id=1) 
>>> b.entry_set.all() # Returns all Entry objects related to Blog.
# b.entry_set is a Manager that returns QuerySets. 
>>> b.entry_set.filter (headline__contains='Lennon') 
>>> b.entry_set.count()

>>> b = Blog.objects.get (id=1) 
>>> b.entries.all() # Returns all Entry objects related to Blog. 
# b.entries is a Manager that returns QuerySets. 
>>> b.entries.filter (headline__contains='Lennon') 
>>> b.entries.count()
You cannot access a reverse ForeignKey Manager from the class; it must be accessed from an instance: 
>>> Blog.entry_set
add(obj1, obj2, ...) 
    Adds the specified model objects to the related object set. 
create(**kwargs) 
    Creates a new object, saves it and puts it in the related object set. Returns the newly created object. 
remove(obj1, obj2, ...) 
    Removes the specified model objects from the related object set. 
clear() 
    Removes all objects from the related object set. 
    
many-to-many类型: 
e = Entry.objects.get (id=3) 
e.authors.all() # Returns all Author objects for this Entry. 
e.authors.count() 
e.authors.filter (name__contains='John') 
a = Author.objects.get (id=5) 
a.entry_set.all() # Returns all Entry objects for this Author.
one-to-one 类型: 
class EntryDetail(models.Model): 
    entry = models.OneToOneField(Entry) 
    details = models.TextField()
ed = EntryDetail.objects.get (id=2) 
ed.entry # Returns the related Entry object

使用sql语句进行查询:
def my_custom_sql(self): 
    from django .db import connection 
    cursor = connection.cursor() 
    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz]) 
    row = cursor.fetchone() 
    return row
分享到:
评论

相关推荐

    PyPI 官网下载 | django-queryset-csv-1.0.2.tar.gz

    在Django中,QuerySet是数据库操作的核心接口,它可以执行SQL查询并返回模型实例的集合。QuerySet对象不仅包含了查询数据库的所有信息,还提供了丰富的API供开发者进行过滤、排序、聚合等操作。 **django-queryset-...

    django 数据库返回queryset实现封装为字典

    虽然这个方法不是Django原生的,但在某些场景下,比如直接操作数据库连接(非ORM方式),可能会用到。但通常,我们更倾向于使用Django提供的`model_to_dict`和序列化工具,因为它们与Django的ORM更加紧密集成,提供...

    django queryset 去重 .distinct()说明

    我就废话不多说了,大家还是直接看代码吧! contacts = ExternalContacts.objects.filter...合并出来的queryset,再去重。 补充知识:Python——深入理解urllib、urllib2及requests(requests不建议使用?)

    django 中QuerySet特性功能详解

    Book表的数据显示 id title price publish_id 2 Linux 30 1 3 项塔兰 45 2 ... ret1 = Book.objects.all()[0] #QuerySet支持索引,切片操作 # print(ret1) #linux 得到一个具体的对象 ret2 = Book.objec

    django-data-interrogator:django-data-interrogator是一个表格生成器插件,允许用户轻松地从Django数据库中提取信息

    从本质上讲,它为从Django数据库queryset API构建表格数据提供了一个聪明而明智的前端-尤其是values , filter , order_by和少数批注。 内容 将数据询问器添加到您的INSTALLED_APPS : INSTALLED_APPS = ( # ....

    Django框架 querySet功能解析

    Django是一个高级PythonWeb...通过上面的解析,我们可以看到Django的QuerySet功能非常强大,使用时既能够提高代码的可读性,也能提升数据库操作的效率。掌握QuerySet的高级用法是每个Django开发者必须要迈出的一步。

    django queryset相加和筛选教程

    在Django中,QuerySet是用于操作数据库的强大工具,它提供了高级的查询功能,使得开发者无需直接编写SQL语句即可完成复杂的数据库操作。本教程主要关注如何使用QuerySet进行对象的相加(合并)和筛选。 首先,让...

    浅谈在django中使用filter()(即对QuerySet操作)时踩的坑

    代码伺候: 先看如下代码: 例1:  message = Message.objects.filter(pk=message_id2) ...可正常从QuerySet中读取数据,并打印出来,无误。可是无法将数据同步到数据库中。 (1)all()返回的是

    Python的Django框架实现数据库查询(不返回QuerySet的方法)

    在Django中,这些方法提供了灵活性,允许开发者高效地处理数据库操作,而不必总是返回整个QuerySet。了解并熟练使用这些方法能够帮助提升代码的效率和可读性。在实际项目中,根据具体需求选择合适的方法,可以有效地...

    Django QuerySet查询集原理及代码实例

    Django的QuerySet是其ORM(Object-Relational Mapping)系统的核心组成部分,它是用来与数据库进行交互的主要工具。在Django中,当你从模型Manager(如`objects`)上调用诸如`all()`, `filter()`, `exclude()`, `order...

    PythonDjango支持像PostgresCitus这样的分布式多租户数据库

    在Citus中,我们可以使用Django ORM的`queryset.filter()`方法,结合`__in`操作符和租户标识符来限制查询范围,确保每个租户只能访问自己的数据。 然而,与Citus集成也带来了挑战。由于Citus的数据分布特性,一些...

    Django 查询数据库并返回页面的例子

    本文将介绍在Python框架Django中如何进行数据库查询以及将查询结果渲染到Web页面上的过程。Django是一个高级的、开源的Web应用框架,它遵循模型-视图-控制器(MVC)设计模式,提供了快速开发Web应用的便捷性。 首先...

    django执行数据库查询之后实现返回的结果集转json

    请注意,为了提高性能,避免在循环中进行数据库操作,可以考虑使用Django的查询集方法,如`values()`和`annotate()`,直接获取所需字段的字典形式。同时,确保正确管理和关闭数据库连接,以防止资源泄漏。

    Python-Django与MongoDB数据库的连接器

    在处理查询时,Django的QuerySet API仍然适用,但要注意某些SQL特性可能不适用于MongoDB,因为它们具有不同的查询语法。Djongo会尽可能地模拟Django的查询行为,但对于不兼容的部分,你需要使用MongoDB的原生查询...

    7. Django 模型与数据库

    模型类还有一些内置的方法,如`save()`用于保存到数据库,`delete()`用于删除对象,以及`objects`属性,它是Django的查询集(QuerySet)对象,用于执行数据库查询。 数据库操作在Django中非常直观。例如,我们可以...

    django框架基于queryset和双下划线的跨表查询操作详解

    Django的查询集(QuerySet)是一个强大的工具,用于从数据库检索信息。通过使用双下划线(__)的语法,Django模型间的关联可以被高效地查询,从而实现跨表查询。 跨表查询是数据库操作中常见的需求,它允许从多个...

Global site tag (gtag.js) - Google Analytics