Django自己提供了很是强大易使用的ORM组件,而且支持多种数据库。python
配置链接数据文件mysql
在本身建立的project 目录下编辑settings.pyweb
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # mysql 数据库 'NAME': 'dbname', #确保此数据库已存在 'HOST':'', 'PORT':'', 'USER':'root', 'PASSWORD':'' } }
假设下面的概念,字段关系:sql
1,一个做者有姓,名及email地址shell
2,出版商有名称,地址,所在城市,省,国家,网站数据库
3,书籍有书名和出版日期。它有一个或多个做者,只有一个出版商django
#models.py # 一张表定义一个类,这里再也不须要单独定义关联表 from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) # 多对多 publisher = models.ForeignKey(Publisher) # 一对多 publication_date = models.DateField()
代码完成后,就须要建立表了。python3.x
第一步,在Django项目中 激活这些模型。将上面的模型所在的app添加到配置文件的安装应用列表中。session
# settings.py INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'app01', # 本身所建立的Django项目名 )
命令行模式:app
python manage.py makemigrations # 生成同步记录
python manage.py migrate # 开始同步数据库
数据同步完成以后就能够在命令行模式 使用 python manage.py shell 就能够进入Django提供的高级python API
>>> from books.models import Publisher >>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue', ... city='Berkeley', state_province='CA', country='U.S.A.', ... website='http://www.apress.com/') # 添加数据 >>> p1.save() # 保存到数据库 >>> p2 = Publisher(name="O'Reilly", address='10 Fawcett St.', ... city='Cambridge', state_province='MA', country='U.S.A.', ... website='http://www.oreilly.com/') >>> p2.save() >>> publisher_list = Publisher.objects.all() #读取数据 >>> publisher_list [<Publisher: Publisher object>, <Publisher: Publisher object>]若是须要一步建立与存储到数据库,就须要使用 objects.create() 方法
>>> p1 = Publisher.objects.create(name='Apress', ... address='2855 Telegraph Avenue', ... city='Berkeley', state_province='CA', country='U.S.A.', ... website='http://www.apress.com/') # 直接写如数据库 >>> p2 = Publisher.objects.create(name="O'Reilly", ... address='10 Fawcett St.', city='Cambridge', ... state_province='MA', country='U.S.A.', ... website='http://www.oreilly.com/') >>> publisher_list = Publisher.objects.all() >>> publisher_list
当咱们打印整个publisher 列表时,咱们没有获得想要的信息,没法把对象区分。
[<Publisher: Publisher object>, <Publisher: Publisher object>]为了解决这个问题,只须要为publisher对象添加一个方法。这个方法告诉python 若是将对象以unicode的方式显示出来。
def __str__(self): return self.name # name为须要显示的字段名。能够返回多个 # return "<%s %s>" %(self.first_name,self.last_name)注:在python 2.x 里面使用 __unicode_() python3.x 里面使用 __str__()
插入数据:
p = Publisher(name='Apress', ... address='2855 Telegraph Ave.', ... city='Berkeley', ... state_province='CA', ... country='U.S.A.', ... website='http://www.apress.com/') p.save() # 这一步才会插入数据库更新数据:
>>> p.name = 'Apress Publishing' # 直接赋值,就是更改数据 >>> p.save() # 保存
>>> Publisher.objects.all() [<Publisher: Apress>, <Publisher: O'Reilly>] # 至关于SQL 语句 SELECT id, name, address, city, state_province, country, website FROM books_publisher;注意:Django 在选择全部数据时并无使用 select * ,而是显示列出了全部字段。由于 select * 会更慢,并且最重要的是列出全部字段遵循了python 界的一个信条:明言胜于暗示
filter() 方法进行数据过滤
>>> Publisher.objects.filter(name='Apress') [<Publisher: Apress>]能够使用多个 filter() 来缩小范围:
>>> Publisher.objects.filter(country="U.S.A.", state_province="CA") [<Publisher: Apress>]进行模糊匹配:
>>> Publisher.objects.filter(name__contains="press") [<Publisher: Apress>] # 在name和contains 之间有两个下划线。# Django 使用双下划线来代表会进行一些操做。
转为原生的SQL:
SELECT id, name, address, city, state_province, country, website FROM books_publisher WHERE name LIKE '%press%';
使用get() 方法获取单个对象
>>> Publisher.objects.get(name="Apress") <Publisher: Apress>这里返回的是单个对象,而不是列表。因此若是结果是多个对象,就会致使抛出异常。
若是没有查询到结果也会抛出异常:
>>> Publisher.objects.get(name="Penguin") Traceback (most recent call last): ... DoesNotExist: Publisher matching query does not exist.这个DoesNotExist 异常是 publisher 这个model 类的一个属性,即publisher.DoesNotExist。在应用中能够捕获并处理这个异常。
try: p = Publisher.objects.get(name='Apress') except Publisher.DoesNotExist: print "Apress isn't in the database yet." else: print "Apress is in the database."
使用order_by() 方法进行排序
>>> Publisher.objects.order_by("name") [<Publisher: Apress>, <Publisher: O'Reilly>]对多个字段进行排序
>>> Publisher.objects.order_by("state_province", "address") [<Publisher: Apress>, <Publisher: O'Reilly>]倒序,在前面加一个 - 前缀:
>>> Publisher.objects.order_by("-name") [<Publisher: O'Reilly>, <Publisher: Apress>]尽管和灵活,可是每次都要用 order_by() 显得有点啰嗦。大多数只会经过某些字段进行排序,这中状况下Django 能够指定模型的缺省排序方式:
class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() def __unicode__(self): return self.name class Meta: ordering = ['name'] # 缺省排序字段class Meta ,内嵌于Publisher这个类的定义中(若是class Publisher是顶格的,那么class Meta 在它之下不要缩进4个空格)。能够在任意一个模型中使用Meta类,来设置一些与特定模型相关的选择。Meta 还能够设置其余选项。若是设置了这个选项,那么触发检索时特地额外使用了 order_by() ,不然,当你使用Django的数据库API去检索时,Publisher对象的相关返回值默认都会按照name字段排序。
同时进行过滤和排序查询
>>> Publisher.objects.filter(country="U.S.A.").order_by("-name") [<Publisher: O'Reilly>, <Publisher: Apress>]
只显示第一条数据
>>> Publisher.objects.order_by('name')[0] <Publisher: Apress>[ ] 内相似一个列表
好比取第一条和第二条
>>> Publisher.objects.order_by('name')[0:2]可是不支持 负索引
在插入和更新数据中,使用save()方法,这个方法会更新一行里面的说有列。
>>> p = Publisher.objects.get(name='Apress') >>> p.name = 'Apress Publishing' >>> p.save() # 原生的SQL语句: SELECT id, name, address, city, state_province, country, website FROM books_publisher WHERE name = 'Apress'; UPDATE books_publisher SET name = 'Apress Publishing', address = '2855 Telegraph Ave.', city = 'Berkeley', state_province = 'CA', country = 'U.S.A.', website = 'http://www.apress.com' WHERE id = 52; #假设ID为52从原生的SQL来看save() 方法是更新了一行内的全部字段。
若是想只更新某一个字段
>>> Publisher.objects.filter(id=52).update(name='Apress Publishing')转为的原生SQL
UPDATE books_publisher SET name = 'Apress Publishing' WHERE id = 52;update()方法对任何结果集都有效。所以能够同时更新多条记录
>>> Publisher.objects.all().update(country='USA') 2 #update()方法会返回一个整数数值,表示受到影响的记录条数。
使用delete()方法
>>> p = Publisher.objects.get(name="O'Reilly") >>> p.delete() >>> Publisher.objects.all() [<Publisher: Apress Publishing>] # 同也能够删除多条数据 >>> Publisher.objects.filter(country='USA').delete() >>> Publisher.objects.all().delete() >>> Publisher.objects.all() []在删除数据的时候要当心,一旦使用all()方法,全部的数据将会被删除。
若是须要删除部分的数据,就不须要调用all()方法。
>>> Publisher.objects.filter(country='USA').delete()