您的位置:首页 > 编程语言 > Python开发

Django数据库操作(python)

2013-10-25 15:57 507 查看
简单博客models实体对象

from django.db import models

class Blog(models.Model):

    name = models.CharField(max_length=100)

tagline = models.TextField()

Pub_date =DateField()

    def __str__(self):

        return self.name

class Author(models.Model):

    name = models.CharField(max_length=50)

    email = models.EmailField()

    def __str__(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 __str__(self):

        return self.headline

1、Save() :   Django不会保存到数据库. save() 方法没有返回值

>>> from mysite.blog.models import Blog

>>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')

>>> b.save()

2、自增主键:每个数据库模型都会添加一个自增主键字段,即 id 

>>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')

>>> b2.id     # Returns None, because b doesn't have an ID yet.

None

>>> b2.save()

>>> b2.id     # Returns the ID of your new object.

14

3、保存对对象做修改:在后台执行了 UPDATE 这一SQL语句。

>>> b5.name = 'New name'

>>> b5.save()

4、获取对象:

    当你从数据库中获取对象的时候,你实际上用 Manager 模块构造了一个 QuerySet ,这个 QuerySet 知道怎样去执行SQL语句并返回你想要的对象。

>>> blogs = Blog.objects.filter(author__name__contains="Joe")   【过滤数据获取】

>>> blogs = Blog.objects.get(id=1)  【获取单个对象】

>>> blogs = Blog.objects.all()  【获取所以对象】

5、缓存与查询集:

为了减少数据库访问次数,每个 QuerySet 包含一个缓存,要写出高效的代码,理解这一点很重要。

queryset = BLog.objects.all()

print [p.name for p in queryset] # Evaluate the query set.

print [p.pub_date for p in queryset] # Reuse the cache from the evaluation.

6、过滤对象:用 filter() 和 exclude() 方法可以实现这样的功能

>>> y2006 = Entry.objects.filter(pub_date__year=2006)

>>> not2006 = Entry.objects.exclude(pub_date__year=2006)

7、级联过滤器:

>>> qs = Entry.objects.filter(headline__startswith='What')

>>> qs = qs..exclude(pub_date__gte=datetime.datetime.now())

>>> qs = qs.filter(pub_date__gte=datetime.datetime(2005, 1, 1))

8、限量查询集:

数据切片的语法来限定 QuerySet 的结果数量,这和SQL中的 LIMIT 和 OFFSET 语句是一样的。

>>> Entry.objects.all()[:5]  【返回前五个条目( LIMIT 5 )】

>>> Entry.objects.all()[5:10] 【返回第六到第十个条目( OFFSET 5 LIMIT 5 )】

>>> Entry.objects.all()[:10:2] 【回前十个对象中的偶序数对象的列表时】

>>> Entry.objects.order_by('headline')[0]  【单个 对象而不是一个列表时(SELECT foo FROM bar LIMIT 1)】

9、删除对象

b = Blog.objects.get(id=2)

b.delete()

二、返回新的 QuerySets 的 查询方法

1、filter(**lookup)

返回一个新的 QuerySet ,包含匹配参数lookup的对象。

 >>>Entry.objects.filter(pub_date__year=2005).

2、exclude(**kwargs)

返回一个新的 QuerySet ,包含不匹配参数kwargs的对象。

>>> Entry.objects.exclude(pub_date__year=2005).

3、order_by(*fields)

默认情况下,会返回一个按照models的metadata中的``ordering``选项排序的``QuerySet``(请查看附录B)。你可以调用``order_by()``方法按照一个特定的规则进行排序以覆盖默认的行为:

>>> Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')

4、distinct()

 这消除了查询结果中的重复行,就像使用”SELECT DISTINCT”在SQL查询一样

 Entry.objects.filter(pub_date__year=2005).distinct()

5、values(*fields)

返回一个特殊的QuerySet相当于一个字典列表,而不是model的实例

>>> Blog.objects.filter(name__startswith='Beatles').values()

[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]

6、dates(field, kind, order) :

参数一:字段名称;参数二:year/month/day;参数三:排序 order="DESC/ASE"

返回QueryDet,指定是DateField或DateTimeField字段名称,日期数据。

Kind ="Year"返回所以年份值的数据列表

Kind="Mouth"访问所以月份值的数据列表

Kind="Day"访问所以月份值的数据列表

7、select_related()  如下尽可能的外键

>>> e = Entry.objects.select_related().get(id=5)

# Doesn't hit the database, because e.blog has been prepopulated

# in the previous query.

>>> b = e.blog

8、extra()

Django查询语法本身没有复杂Where子句,用extra函数就可以使用Where查询子句。

>>>Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})

执行SQL字符串

>>> subq = 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'

>>> Blog.objects.extra(select={'entry_count': subq})

   Where 条件查询   中的使用IN

>>> Entry.objects.extra(where=['id IN (3, 4, 5, 20)'])

    Where条件中使用参数方式一

>>>Entry.objects.extra(where=['headline=%s'], params=['Lennon'])

Where条件使用参数方式二

>>>Entry.objects.extra(where=["headline='%s'" % name])

Where条件中使用参数方式三

>>>Entry.objects.extra(where=['headline=%s'], params=[name])

三、返回另外一个QuerySet对象

1、Create(**kwargs)   这个快捷的方法可以一次性完成创建并保证对象

常用保存对象

>>>p = Person(first_name="Bruce", last_name="Springsteen")

>>> p.save()

一行保存对象,简介方式保存对象

>>>p = Person.objects.create(first_name="Bruce", last_name="Springsteen") 

2、get_or_create(**kwargs)

根据参数获取一个对象,如果对象存在则返回对象,如果对象不操作,则创建对象。

(object,Created)=Enty.object.get_or_create(**kwargs)

  返回参数中:Object是获取或添加的对象,Created是Boolean值返回是否新创建的对象。

obj, created = Person.objects.get_or_create(

     first_name = 'John',

     last_name  = 'Lennon',

     defaults   = {'birthday': date(1940, 10, 9)}

)

3、count :统计实体对象集合的记录

 >>>Entry.objects.count()

>>> Entry.objects.filter(headline__contains='Lennon').count()

4、in_bulk(id_list):根据实体对象中的主键ID集合,返回该ID集合中的数据集合。

>>> Blog.objects.in_bulk([1])

{1: Beatles Blog}

>>> Blog.objects.in_bulk([1, 2])

{1: Beatles Blog, 2: Cheddar Talk}

>>> Blog.objects.in_bulk([])

{}

5、latest(field_name=None):   返回最新、最后添加的对象。参数ield_name:列名

>>>Entry.objects.latest('pub_date')

6、__exact :精确匹配

>>>Entry.objects.get(headline__exact="Man bites dog") 

>>>Blog.objects.get(id__exact=14) # Explicit form       

>>> Blog.objects.get(id=14)      # 等价上面一种方式        

7、__iexact:精确匹配(大小写无关)

>>> Blog.objects.get(name__iexact='lhj588 blog')

可以把“Lhj588 Blog"、"lhj588 blog"、"LHJ588 BLOG"匹配出来

8、__contains:执行严格区分大小写的内容包含检测:

>>>Blog.objects.get(name__contains='lhj')

  可以匹配Blog name包含"lhj"区分大小写

9、__icontains执行一个忽略大小写的内容包含检测:

>>>Blog.objects.get(name__icontains='lhj')

可以匹配Blog name包含"lhj"不区分大小写

10、__gt:筛选大于

>>>Entry.objects.filter(id__gt=5)

11、__gte:筛选大于等于

>>>Entry.objects.filter(id__gte=10)

12、 __lt: 筛选小于

>>>Entry.objects.filter(id__lt=15)

13、__lte:筛选小于等于

>>>Entry.objects.filter(id__lte=20)

14、__in:筛选出包含在给定列表中的数据

>>>Entry.objects.filter(id__in=[1,4,8])

这会返回所有ID为1,4,或8的记录对象。

15、__startswith:开头匹配,区分大小写

  >>>Blog.objects.filter(name__startswith='Lhj')

    返回标题Lhj588 blog和Lhj888 blog,但是返回lhj588 blog 和lhj888 blog 

16、__istartswith:开头匹配,不区分大小写

>>>Blog.objects.filter(name__istartswith='Lhj')

返回标题Lhj588 blog和Lhj888 blog,同时返回lhj588 blog 和lhj888 blog

17、__endswith: 末尾匹配,区分大小写

>>>Blog.objects.filter(name__endswith='Blog')

    返回标题Lhj588 Blog和Lhj888 Blog,但是返回lhj588 blog 和lhj888 blog 

18、__iendswith:末尾匹配,不区分大小写

>>>Blog.objects.filter(name__iendswith='Blog')

返回标题Lhj588 'Blog'和Lhj888 'Blog',同时返回lhj588 blog 和lhj888 blog

19、__range:范围检测 ,    就像SQL中的BETWEEN and 

>>> start_date = datetime.date(2005, 1, 1)

>>> end_date = datetime.date(2005, 3, 31)

>>> Blog.objects.filter(pub_date__range=(start_date, end_date))

20、__year, __month,and __day:对date/datetime类型字段严格匹配年、月或日

>>>Blog.objects.filter(pub_date__year=2005) #查找年份数据

>>> Blog.objects.filter(pub_date__month=12) #查找月份数据

>>> Blog.objects.filter(pub_date__day=3) #日查找数据

#查找12月25日数据 

>>> Blog.objects.filter(pub_date__month=12, pub_date_day=25)

21、__isnull:

使用``True``或``False``,则分别相当于SQL语句中的``IS NULL``和``IS NOT NULL``

>>>Blog.objects.filter(pub_date__isnull=True)

22、主键查询快捷方式:

>>>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

>>>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

23、使用Q对象做联合查找

``filter()``等语句的参数都是取AND运算。如果想要执行更多的联合语句(如``OR``语句),你可以使用 ``Q``对象。

Q 对象 (django.db.models.Q ) 是一个用来囊括参数间连接的对象。这些参数会放在指定的域查询的位置。

Q(name__startswith='Lhj')   

同SQL: WHERE name LIKE 'Lhj'%'

Q(name__startswith='Lhj') | Q(name__startswith='loker')

同SQL:WHERE name LIKE 'Lhj%' OR name LIKE 'loker%'

你可以用运算符``&``和 |``连接``Q 对象组成任意复杂的语句。你也可以使用附加组。

Blog.objects.get(

    Q(name__startswith='Lhj'),

    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))

)

同SQL:SELECT * FROM blog WHERE nameLIKE 'Lhj%'

    AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

四、关系对象

对象关系型模型:一对一 、一对多、多对多

1、跨越关系查找

   >>>Entry.objects.filter(blog__name__exact=Lhj588 Blog')

   >>>Blog.objects.filter(entry__headline__contains='Lennon')

2、外键关系

如果一个模型里面有一个 ForeignKey 字段,那么它的实例化对象可以很轻易的通过模型的属性来访问与其关联的关系对象

e = Entry.objects.get(id=2)

e.blog = some_blog

e.save()

e = Entry.objects.select_related().get(id=2)

print e.blog

e = Entry.objects.get(id=2)

print e.blog

3、外键的反引用关系

外键关系是自动对称反引用关系的,这可由一个外键可以指向另一个模型而得知.

如果一个源模型含有一个外键,那么它的外键模型的实例,可以利用”Manager”返回这个源模型的 所有实例.默认的这个”Manager”叫做”FOO_set”,这个”FOO”是源模型的名字,小写字母,这个”Manager”将返 回”QuerySets”,对这个QuerySets进行过滤和操作,就像在检索对象章节中介绍的.

b =Blog.objects.get(id=1)

b.entry_set.all()   #返回到博客相关的所有入口对象。

b.entry_set.filter(headline__contains='Lennon')

b.entry_set.count()

通过在”ForeignKey()”中定义related_name参数,你可以重载”FOO_set”名字.举例,如果把”Entry”模型修改为”blog =ForeignKey(Blog, related_name=’entries’)”,

b= Blog.objects.get(id=1)

b.entries.all() # 返回到博客相关的所有入口对象。 

b.entries.filter(headline__contains='Lennon')

b.entries.count()

4、关系 (连接)

当你在 model 中定义了一个关系字段(也就是,一个ForeignKey, OneToOneField, 或 ManyToManyField). Django 使用关系字段的名字为 model 的每个实例添加一个 描述符. 在访问对象或关联对象时, 这个描述符就象一个常规属性. 举例来说, mychoice.poll 会返回 Choice 实例对象关联的 Poll 对象.

通过下面的关系,连接可以以非显式的方式进行: choices.objects.filter(poll__slug="eggs") 得到一个 Choice 对象列表, 这些对象关联的 Poll 对象的 slug 字段值为 eggs. 允许多级连接.

通过一个对象实例的便利函数(convenience functions)就可直接查询该对象的关联对象. 举例来说, 如果 p 是一个 Poll 实例, p.choice_set() 将返回所有关联的 Choice 对象列表. 聪明的读者会注意到它等价于 choices.objects.filter(poll__id=p.id), 只是更加清晰.

每一种关系类型会为关系中的每个对象自动创建一系列便利方法(类似 choice_set() 这样的方法).这些方法被双向创建, 这样被关联的对象就不需要明确的定义反向关系, 这一切都是自动完成的.

5、一对一(One-to-one relations)

one-to-one 关系中的每个对象拥有一个 get_relatedobjectname() 方法. 举例来说:

class Place(meta.Model):

    # ...

class Restaurant(meta.Model):

    # ...

    the_place = meta.OneToOneField(places.Place)

在上面的例子里, 每个 Place 会自动拥有一个 get_restaurant() 方法, 且每个 Restaurant 会自动拥有一个 get_the_place() 方法.

6、多对一(Many-to-one relations)

在 many-to-one 关系中, 关联对象(Many)会自动拥有一个 get_relatedobject() 方法. 被关联的对象(one)会自动拥有 get_relatedobject(), get_relatedobject_list(), 和 get_relatedobject_count() 方法 (功能与模块级的 get_object(), filter(), 和 get_count() 相同).

在上面的民意测试例子里, 一个 Poll 对象 p 自动拥有下列方法:

p.get_choice()

p.get_choice_list()

p.get_choice_count()

Choice 对象 c 则自动拥有下面的方法:

c.get_poll()

7、多对多关系(Many-to-Many):

在多对多关系的两端,都可以通过相应的API来访问另外的一端。 API的工作方式跟前一节所描述的反向一对多关系差不多。

唯一的不同在于属性的命名:定义了``ManyToManyField``的model的实例使用属性名称本身,另外一端的model的实例则使用model名称的小写加上``_set``来活得关联的对象集(就跟反向一对多关系一样)

e = Entry.objects.get(id=3)

e.authors.all() # 返回所有Author对象

e.authors.count()

e.authors.filter(name__contains='John')

a = Author.objects.get(id=5)

a.entry_set.all() #返回该作者所有入境的对象。

五、额外方法

1、get_FOO_display() :设置字段隐藏值,如:性别,M=Male,F=Female

GENDER_CHOICES = (

    ('M', 'Male'),

    ('F', 'Female'),

)

class Person(models.Model):

    name = models.CharField(max_length=20)

gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

>>> p = Person(name='lhj', gender='M')

>>> p.save()

>>>p.gender

'M'

>>>p.get_gender_display()

'Male'

2、get_object_or_404():

获取对象,如果对象不存在它将引发 Http404,

e = get_object_or_404(Entry, pk=3)

a = get_object_or_404(e.authors, name='Fred')

e = get_object_or_404(Entry.recent_entries, pk=3)

3、get_list_or_404()

et_list_or_404 行为与 get_object_or_404() 相同,但是它用 filter() 取代了 get() 。如果列表为空,它将引发 Http404 。

4、get_next_by_FOO(**kwargs) 和get_previous_by_FOO(**kwargs)

不存在 null=True 的每个 DateField 和 DateTimeField 自动拥有 get_next_by_FOO() 和 get_previous_by_FOO() 方法, 此处的 FOO 是字段的名字. 它们分别返回该字段的上一个对象和下一个对象. 如果上一对象或下一对象不存在,则抛出 *DoesNotExist 异常.

这两个方法均接受可选关键字参数, 这些参数应该遵循上文中 "Field 查询" 中提到的格式.

注意如果遇到相同值的对象, 这些方法会使用 ID 字段进行检查. 这保证了没有一条记录会被跳过或重复记数.参阅 lookup API sample model_ ,那里有一个完整的例子.

5、get_FOO_filename() 

对一个 FileField 对象来说, 它自动拥有一个 get_FOO_filename() 方法. 这里 FOO 是字段名,它根据你的 MEDIA_ROOT 设置返回一个完整的路径名称.

注意 ImageField 技术上是 FileField 的一个子类, 因此每个有 ImageField 的 model 自动拥有此方法.

6、get_FOO_url()

含有 FileField 字段的每个对象自动拥有一个 get_FOO_url() 方法,这里的 FOO 是字段的名字. 该方法根据你的 MEDIA_URL 设置返回该文件的完整 URL ,如果 MEDIA_URL 设置为空, 该方法返回一个空的字符串.

7、get_FOO_size()

含有 FileField 字段的每个对象自动拥有一个 get_FOO_filename() 方法, 这里的 FOO 是字段的名字. 该方法返回文件的长度(字节数).(在后台, Django 使用 os.path.getsize.)

8、save_FOO_file(filename, raw_contents)

含有 FileField 字段的每个对象自动拥有一个 get_FOO_filename() 方法, 这里的 FOO 是字段的名字. 该方法使用给定的文件名将文件保存到文件系统.. 如果同目录下已经有同名文件存在,Django 会在文件名后添加一个下划线(扩展名之前)直到文件名有效为止(也就是如果加了下划线还重名,就再加....直到没有重名为止).

9、get_FOO_height() 和 get_FOO_width()

含有 ImageField 字段的每个对象自动拥有 get_FOO_height() 和 get_FOO_width() 方法, 这里的 FOO 是字段的名字. 它们返回相应的图片高度和宽度(整数,以像素计).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Python Django 数据库