VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • 建立一个更高级别的查询 API:正确使用Django ORM 的方式

摘要

在这篇文章里,我将以反模式的角度来直接讨论Django的低级ORM查询方法的使用。作为一种替代方式,我们需要在包含业务逻辑的模型层建立与特定领域相关的查询API,这些在Django中做起来不是非常容易,但通过深入地了解ORM的内容原理,我将告诉你一些简捷的方式来达到这个目的。

概览

当编写Django应用程序时,我们已经习惯通过添加方法到模型里以此达到封装业务逻辑并隐藏实现细节。这种方法看起来是非常的自然,而且实际上它也用在Django的内建应用中。

1
2
3
4
>>>from django.contrib.auth.modelsimport User
>>> user= User.objects.get(pk=5)
>>> user.set_password('super-sekrit')
>>> user.save()

这里的set_password就是一个定义在django.contrib.auth.models.User模型中的方法,它隐藏了对密码进行哈希操作的具体实现。相应的代码看起来应该是这样:

1
2
3
4
5
from django.contrib.auth.hashersimport make_password
class User(models.Model):
    # fields go here..
    def set_password(self, raw_password):
        self.password= make_password(raw_password)

我们正在使用Django,建立一个特定领域的顶部通用接口,低等级的ORM工具。在此基础上,增加抽象等级,减少交互代码。这样做的好处是使代码更具可读性、重用性和健壮性。

我们已经在单独的例子中这样做了,下面将会把它用在获取数据库信息的例子中。

为了描述这个方法,我们使用了一个简单的app(todo list)来说明。

注意:这是一个例子。因为很难用少量的代码展示一个真实的例子。不要过多的关心todo list继承他自己,而要把重点放在如何让这个方法运行。

下面就是models.py文件:

1
2
3
4
5
6
7
8
9
from django.dbimport models
 
PRIORITY_CHOICES= [(1,'High'), (2,'Low')]
 
class Todo(models.Model):
    content= models.CharField(max_length=100)
    is_done= models.BooleanField(default=False)
    owner= models.ForeignKey('auth.User')
    priority= models.IntegerField(choices=PRIORITY_CHOICES, default=1

想像一下,我们将要传递这些数据,建立一个view,来为当前用户展示不完整的,高优先级的 Todos。这里是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
def dashboard(request):
 
    todos= Todo.objects.filter(
        owner=request.user
    ).filter(
        is_done=False
    ).filter(
        priority=1
    )
 
    return render(request,'todos/list.html', {
        'todos': todos,
    })

相关教程