from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __str__(self): # __unicode__ on Python 2
return self.name
class Author(models.Model):
name = models.CharField(max_length=200)
email = models.EmailField()
def __str__(self): # __unicode__ on Python 2
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateField()
mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
rating = models.IntegerField()
def __str__(self): # __unicode__ on Python 2
return self.headline
以下内容将以上述代码为例子说明
1.创建类
为了在python类中表示数据库表单数据,django使用一个直觉的系统: 一个model类代表一个数据库表,一个实例代表数据库表中一个特定的记录。为了创建一个对象,通过关键字参数实例化,然后调用save()方法保存到数据库中。
from blog.models import Blog
b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
b.save()
2.Saving changes to objects
为了保存已存在数据库中的对象的变化,使用save().
b5.name = 'New name'
b5.save()
3. Saving ForeignKey and ManyToManyField fields
from blog.models import Entry
entry = Entry.objects.get(pk=1)
cheese_blog = Blog.objects.get(name="Cheddar Talk")
entry.blog = cheese_blog
entry.save()
更新一个many-to-many字段有些不一样的地方,在字段上使用add()方法来在关系上增加一个记录.
from blog.models import Author
joe = Author.objects.create(name="Joe")
entry.authors.add(joe)
如果在一次add中增加多个记录,传入多个参数,
john = Author.objects.create(name="John")
paul = Author.objects.create(name="Paul")
george = Author.objects.create(name="George")
ringo = Author.objects.create(name="Ringo")
entry.authors.add(john, paul, george, ringo)
4.检索类
为了检索类,通过model类上的管理器构造一个QuerySet,一个A QuerySet 代表数据库的一个集合类,它可以有0个或者多个filters. Filters基于给定的参数缩小查询结果,在SQL中一个QuerySet 相当于一个select语句, 一个 filter相当于一个limiting 子句比如 WHERE 或者 LIMIT.
Blog.objects
b = Blog(name='Foo', tagline='Bar')
b.objects
Traceback:
...
AttributeError: "Manager isn't accessible via Blog instances."
管理器是一个model的QuerySet的主要来源,例如, Blog.objects.all() 返回一个包含所有Blog类的
QuerySet。检索一个数据库表中所有的类,使用Manager的all()
all_entries = Entry.objects.all()
为了返回一个子集,可以增加附加filter条件,常用的有以下两种:
- filter(**kwargs) 返回一个新的QuerySet包含匹配到给定查询参数的类。
- exclude(**kwargs) 返回一个新的QuerySet包含没有匹配到给定查询参数的类。
举例:
Entry.objects.filter(pub_date__year=2006)' 和
Entry.objects.all().filter(pub_date__year=2006)`一样
同样,我们可以使用filter链在,复杂查询中
>>> Entry.objects.filter(
... headline__startswith='What'
... ).exclude(
... pub_date__gte=datetime.date.today()
... ).filter(
... pub_date__gte=datetime(2005, 1, 30)
... )
注:1.每次查询返回的QuerySet都是不同的,2.QuerySet是懒惰的
就是说
q = Entry.objects.filter(headline__startswith="What")
q = q.filter(pub_date__lte=datetime.date.today())
q = q.exclude(body_text__icontains="food")
print(q)
只有最后一个语句才会进行数据库操作。
使用get()方法检索一个单一的类,filter() 方法总是给你一个 QuerySet, 即使只有一个单一的类匹配到查询条件,这种情况下,返回的结果是一个只有一个元素的QuerySet.如果你知道只有一个结果匹配到查询,你可以使用get()方法,该方法直接返回结果类。>>> one_entry = Entry.objects.get(pk=1)
,注意,如果没有结果匹配到查询条件,get()会报DoesNotExist的错误,同样,当查询结果多于一个时,也会报错,MultipleObjectsReturned。
5.Limiting QuerySets
Entry.objects.all()[:10:2]
Entry.objects.order_by('headline')[0]
6.Field lookups
基本查询关键字参数使用以下形式:field__lookuptype=value.相当于sql查询语句中的where子句。
举例:
Entry.objects.filter(pub_date__lte='2006-01-01')
#-->
SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';
Entry.objects.get(headline__exact="Cat bites dog")
#-->
SELECT ... WHERE headline = 'Cat bites dog';
Blog.objects.get(name__iexact="beatles blog")
#: 不区分大小写的匹配。
Entry.objects.get(headline__contains='Lennon')
#: 有大小写区分的包含测试
startswith, endswith Starts-with and ends-with search,
7,Comparing objects
为了比较两个Model对象实例,使用==即可。后台,将会进行对比两个model的主键
8.Deleting objects
>>> e.delete()
(1, {'weblog.Entry': 1})
每个QuerySet都有一个delete()方法,你可以在查询后调用delete方法。
9.Copying model instances
尽管还没有内建的方法用来复制model实例,创建一个所有字段值都复制的新的实例也是很容易的,最简单的情况是,设置pk为None,
blog = Blog(name='My blog', tagline='Blogging is easy')
blog.save() # blog.pk == 1
blog.pk = None
blog.save() # blog.pk == 2
many-to-many情况
entry = Entry.objects.all()[0] # some previous entry
old_authors = entry.authors.all()
entry.pk = None
entry.save()
entry.authors.set(old_authors)
one-to-one情况
detail = EntryDetail.objects.all()[0]
detail.pk = None
detail.entry = entry
detail.save()