前述内容设置了一个全功能管理站点,并可对博客内容进行处理.本节将讨论如何从数据库中获取信息并与其进行交互.Django设置了强大的数据库抽象API,并以此方便地建立、获取、更新以及删除对象.同时,Django中的对象关系映射器兼容于MySQL、PostgreSQL、SQLite、Oracle.须要注意的是,咱们可在项目的settings.py文件中的DATABASES设置项中定义当前项目的数据库.Django可一次与多个数据库协同工做,用户能够对数据库路由器进行编程,以建立自定义路由方案.python
在数据库模型建立完毕后,Django提供了相应的API可与其进行交互.shell
1.5.1 建立对象数据库
打开终端并运行如下命令启动Python shell:django
python manage.py shell
随后输入下列代码行编程
from django.contrib.auth.models import User from blog.models import Post user = User.objects.get(username='admin') post = Post(title='Another post',slug='another-post',body='Post body',author=user) post.save()
下面对上述代码的执行内容进行简要分析.首先,咱们经过用户名admin获取user对象,以下所示:缓存
user = User.objects.get(username='admin')
这里,get()方法可从数据库中获取单一对象.注意,该方法指望获得与查询匹配的结果.若是数据库未返回任何结果,该方法将会抛出DoesNotExist异常:若是数据库返回多条结果,则会抛出MultipleObjectsReturned异常.这两个异常均为与执行查询对应的、模型类的属性.服务器
随后利用定制title、slug以及body建立Post实例,并将以前检索到的用户设置为帖子的做者,以下所示:post
post = Post(title='Another post',slug='another-post',body='Post body',author=user)
!!!注意:测试
此类对象位于内存中,且未实现数据库的持久化操做.spa
最后,利用save()方法将Post对象保存至数据库,以下所示:
post.save()
上述操做在后台执行了INSERT SQL语句.前述内容讨论了在内存中建立对象,并于随后将其持久化至数据库中.除此以外,还可经过create()这一单一操做方式建立对象,并将其持久化至数据库中,以下所示:
Post.objects.create(title='One more post',slug='one-more-post',body='Post body.',author=user)
1.5.2 更新对象
下面修改帖子的标题,并再次保存对象,对应代码以下所示:
post.title = 'New title' post.save()
此处,save()方法执行UPDATE SQL语句.
!!!注意:
当调用了save()方法后,对象的变化内容方能持久化至数据库中.
1.5.3 获取对象
Django对象关系映射机制(ORM)基于Queryset.Queryset表示为一个源自数据库的对象集合,其中包含了多个过滤器以对结果进行限制.咱们了解到经过get()方法获取数据库中的单一对象,并利用Post.objects.get()访问该方法.相应的,每一个Django模型至少包含一个管理器,且默认管理器称做objects.经过模型管理器,用户可获得一个Queryset对象.当从某个表中获取全部的对象时,仅需使用默认对象管理器上的all()方法便可,以下:
all_posts = Post.objects.all()
上述代码显示了Queryset的建立方式,并返回数据库中的所有对象.注意,该Queryset还没有被执行.Django中的Queryset具备延迟性,仅在强制操做下方得以被执行,这种行为使得Queryset更加高效.若是未将Queryset设置为某个变量,而是直接将其写入python shell中,Queryset的SQL语句将被执行--此处将其强制至输出结果中,以下:
Post.objects.all()
1.使用filter()方法
当过滤Queryset时,可食用管理器的filter()方法.例如,可利用下列Queryset得到2019年中发布的所有帖子:
Post.objects.filter(publisher__year=2019)
除此以外,还可经过多个字段进行过滤.例如,可经过包含用户名admin的做者获取发布于2019年的全部帖子,以下:
Post.objects.filter(publisher__year=2019,author__username='admin')
这至关于构建连接多个过滤器的同一Queryset,以下:
Post.objects.filter(publish__year=2017).filter(author__username='admin')
!!!注意:
包含字段查找方法的查询操做可采用两个下划线予以构建,如publish__year;但同一标记也可用于相关模型的访问字段,如author__username.
2.使用exclude()方法
利用过滤器的exclude()方法,可从Queryset中排除特定的结果.例如,可获取标题不包含test的、发布于2019年的所有帖子,以下:
Post.objects.filter(publish__year=2019).exclude(title__startswith='test')
3.使用order_by()方法
利用管理器的order_by()方法,可经过不一样的字段对结果进行排序.例如,可获取以标题排序的所有对象,以下:
Post.objects.order_by('title')
这里,默认为升序操做.固然还可经过负号前缀进行降序排序,以下:
Post.objects.order_by('-title')
1.5.4 删除对象
若是但愿删除某个对象,可经过delete()方法在对象实例中执行这一操做,以下:
post = Post.objects.get(id=1)
post.delete()
!!!注意:
删除对象也会删除ForeignKey对象(on_delete设置为CASCADE)的依赖关系.
1.5.5 评估Queryset
咱们能够链接多个过滤器到一个Queryset上,在Queryset计算以前并不会访问数据库.Queryset仅在如下场合被计算.
1.5.6 建立模型管理器
如前所述,对象表示为每一个模型的默认管理器(可检索数据库中的所有对象).然而,咱们还可针对模型定义定制管理器.下面将建立定制管理器并检索包含published状态的所有帖子.
对此,存在两种方式可向模型中添加管理器,即添加额外的管理器方法,或者修改初始管理器Queryset.其中,第一个方法提供了相应的Queryset API,如Post.objects.my_manager();而第二个方法则提供了Post.my_manager.all().该管理器可经过Post.published.all()检索帖子.
下面编辑models.py文件并添加定制管理器,以下:
class PublishedManager(models.Manager): def get_queryset(self): return super(PublishedManager,self).get_queryset().filer(status='published') class Post(models.Model): # ... objects = models.Manager() # 默认manager published = PublishedManager() # 定制的manager
管理器的get_queryset()方法返回将被执行的Queryset.咱们将覆写该方法,以在最终的Queryset中包含自定义过滤器.以前曾定义了定制管理器,并将其添加值Post模型中,此处可对其加以使用并执行查询.
经过如下命令再次启用开发服务器:
python manage.py shell
此处可利用下列命令检索全部发布的帖子,其对应的标题以test开始
Post.published.filter(title__startswith='test')