【转】django的ORM操作数据库样例

简介:

这个算是我看到的大全了,希望可以解决明天我希望解决的两个问题。。。

复制代码
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 

目录
相关文章
|
2月前
|
关系型数据库 MySQL 数据库
ORM对mysql数据库中数据进行操作报错解决
ORM对mysql数据库中数据进行操作报错解决
79 2
|
16天前
|
关系型数据库 MySQL Java
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
这篇文章是关于如何使用Django框架配置MySQL数据库,创建模型实例,并自动或手动创建数据库表,以及对这些表进行操作的详细教程。
47 0
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
|
2月前
|
存储 关系型数据库 MySQL
【阿里规约】阿里开发手册解读——数据库和ORM篇
从命名规范、建表规范、查询规范、索引规范、操作规范等角度出发,详细阐述MySQL数据库使用过程中所需要遵循的各种规范。
【阿里规约】阿里开发手册解读——数据库和ORM篇
|
19天前
|
SQL Go 数据库
【速存】深入理解Django ORM:编写高效的数据库查询
【速存】深入理解Django ORM:编写高效的数据库查询
42 0
|
2月前
|
数据库 Python
django中数据库外键可以自定义名称吗
django中数据库外键可以自定义名称吗
|
3月前
|
Java 数据库连接 数据库
告别繁琐 SQL!Hibernate 入门指南带你轻松玩转 ORM,解锁高效数据库操作新姿势
【8月更文挑战第31天】Hibernate 是一款流行的 Java 持久层框架,简化了对象关系映射(ORM)过程,使开发者能以面向对象的方式进行数据持久化操作而无需直接编写 SQL 语句。本文提供 Hibernate 入门指南,介绍核心概念及示例代码,涵盖依赖引入、配置文件设置、实体类定义、工具类构建及基本 CRUD 操作。通过学习,你将掌握使用 Hibernate 简化数据持久化的技巧,为实际项目应用打下基础。
133 0
|
3月前
|
数据库 Java 数据库连接
玩转Play Framework的秘密武器:Ebean ORM带你解锁高效数据库操作新姿势,让你的代码从此飞起来!
【8月更文挑战第31天】Play Framework 以其简洁的 API 和高效开发体验著称,Ebean ORM 则是其推荐的对象关系映射(ORM)工具之一。Ebean 可将 Java 对象轻松映射到数据库表,简化数据库交互。本文将指导你在 Play Framework 中使用 Ebean ORM 进行数据库操作,涵盖项目创建、依赖引入、数据库配置、模型定义及 CRUD 操作,并通过示例代码展示实现过程。通过这些步骤,你将学会如何利用 Ebean 的丰富功能,如事务管理、查询构建等,提升 Web 应用的数据库交互能力。
48 0
|
16天前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
50 3
Mysql(4)—数据库索引
|
1天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
10 2