django-model-utils

一个普通例子:

todos = Todo.objects.filter(owner=request.user).filter(is_done=False).filter(priority=1)

弊端:

首先,代码冗长,正式的项目中,将会更加复杂。

其次,泄露实现细节。比如代码中的is_done是BooleanField,如果改变了他的类型,代码就不能用了。

或者就是,意图不清晰,很难理解。

最后,使用中会有重复。

Django 有两个关系密切的与表级别操作相关的构图:managers 和 querysets

manager(django.db.models.manager.Manager的一个实例)被描述成 “通过查询数据库提供给Django的插件”。Manager是表级别功能的通往ORM大门。每一个model都有一个默认的manager,叫做objects。

Quesyset (django.db.models.query.QuerySet) 是“数据库中objects的集合”。本质上是一个SELECT查询,也可以使用过滤,排序等(filtered,ordered),来限制或者修改查询到的数据。用来 创建或操纵 django.db.models.sql.query.Query实例,然后通过数据库后端在真正的SQL中查询。

Manager接口就是个谎言。

QuerySet方法是可链接的。每一次调用QuerySet的方法(如:filter)都会返回一个复制的queryset等待下一次的调用。这也是Django ORM 流畅之美的一部分。

但是当Model.objects 是一个 Manager时,就出现问题了。我们需要调用objects作为开始,然后链接到结果的QuerySet上去。

那么Django又是如何解决呢?

接口的谎言由此暴露,所有的QuerySet 方法基于Manager。

更多:http://www.oschina.net/translate/higher-level-query-api-django-orm

models.py:

from model_utils.managers import PassThroughManager

class NewsQuerySet(models.query.QuerySet):
    def display(self):
        return self.filter(status=1).order_by(‘-create_time‘)

def exece(self, question_id):
        return self.exclude(pk=question_id).display()

class News(models.Model):
    STATUS = (
        (0, u‘不展示‘),
        (1, u‘展示‘),
    )
    title = models.CharField(max_length=20)
    author = models.CharField(max_length=20)
    img = models.ImageField(upload_to=‘upload/news/%Y/%m/%d‘, blank=True, null=True)
    content = models.TextField(blank=True, null=True)
    create_time = models.DateTimeField(auto_now_add=True)
    source = models.CharField(max_length=20)
    status = models.IntegerField(default=1, null=True, blank=True, choices=STATUS)

objects = PassThroughManager.for_queryset_class(NewsQuerySet)()

views.py:

原先:

q = News.objects.all().exclude(id=news_id).filter(status=1).order_by(‘-create_time‘)
现在:

q = News.objects.exece(news_id)

在视图和其他高级应用中使用源生的ORM查询代码不是很好的主意。而是用django-model-utils中的PassThroughManager将我们新加的自定义QuerySet API加进你的模型中,这能给你以下好处:

啰嗦代码少,并且更健壮。
    增加DRY,增强抽象级别。

  将所属的业务逻辑推送至对应的域模型层。

时间: 2024-08-28 09:01:28

django-model-utils的相关文章

Django model :add a non-nullable field 'SKU' to product without a default; we can't do that

You are trying to add a non-nullable field 'SKU' to product without a default; we can't do that (the database needs something to populate existing rows). Please select a fix: 1) Provide a one-off default now (will be set on all existing rows) 2) Quit

Django model与数据库操作对应关系(转)

? Django对数据库的操作分用到三个类:Manager.QuerySet.Model. Manager的主要功能定义表级方法(表级方法就是影响一条或多条记录的方法),我们可以以models.Manager为父类,定义自己的manager,增加表级方法: QuerySet是Manager的方法返回的,是一个可遍历结构,包含一个或多个元素,每个元素都是一个Model 实例,它里面的方法也是表级方法. Model是一条记录的类,它的功能很强大,里面包含外键实体等,它的方法都是记录级方法(都是实例方

转载:django model orM 用字典作为参数,保存数据

作者:轻舞肥羊 日期:2012-12-31 字体大小: 小 中 大   假设有一个字典,里面已经有了所有相关信息,现在想利用这个字典作为参数,跟django model  结合,用很少的代码量保存数据,有什么简便方法,比如有如下定义的model:  程序代码 from django.db import models class MyModel(models.Model):    title=models.CharField(max_length=250)    body= models.Char

Django Model数据访问Making queries

创建完Model之后, Django 自动为你提供一套数据库抽象层的API,利用它可以完成创建,提取,更新,删除对象的操作. 以下面的Model为例: class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() # On Python 3: def __str__(self): def __unicode__(self): return self.name class

django model filter 条件过滤,及多表连接查询、反向查询,某字段的distinct

1.多表连接查询:当我知道这点的时候顿时觉得django太NX了.  class A(models.Model):    name = models.CharField(u'名称')  class B(models.Model):    aa = models.ForeignKey(A)B.objects.filter(aa__name__contains='searchtitle') 1.5 我叫它反向查询,后来插入记录1.5,当我知道的时候瞬间就觉得django太太太NX了.  class

UUIDField在Django Model中的使用经验

今天下午在将数据库从旧库导入到新库时,完成后发现Django网站无法打开,报"ValueError, badly formed hexadecimal UUID string",最终定位到原因是一个UUIDField类型字段的值为0,造成Django无法将0验证为UUID类型,从而引发ValueError异常.现总结UUIDField在Django Model中的使用经验如下. 在Django中UUIDField类型的字段可以作为主键(主键是绝对不可能为NULL值的)使用,这个是丝毫没

django model 类型

Django 通过 models 实现数据库的创建.修改.删除等操作,本文为模型中一般常用的类型的清单,便于查询和使用: AutoField:一个自动递增的整型字段,添加记录时它会自动增长.你通常不需要直接使用这个字段:如果你不指定主键的话,系统会自动添加一个主键字段到你的model.(参阅自动主键字段) BooleanField:布尔字段,管理工具里会自动将其描述为checkbox. CharField:字符串字段,单行输入,用于较短的字符串,如要保存大量文本, 使用 TextField,Ch

Django model字段类型清单

转载:<Django model字段类型清单> Django 通过 models 实现数据库的创建.修改.删除等操作,本文为模型中一般常用的类型的清单,便于查询和使用: AutoField:一个自动递增的整型字段,添加记录时它会自动增长.你通常不需要直接使用这个字段:如果你不指定主键的话,系统会自动添加一个主键字段到你的model.(参阅自动主键字段) BooleanField:布尔字段,管理工具里会自动将其描述为checkbox. CharField:字符串字段,单行输入,用于较短的字符串,

django.db.utils.OperationalError: (1193, &quot;Unknown system variable &#39;storage_engine&#39;&quot;)

django.db.utils.OperationalError: (1193, "Unknown system variable 'storage_engine'") django连接数据库时,配置 "OPTIONS":{"init_command":"SET storage_engine=INNODB;"} 如果mysql数据库的版本是5.6,这句话会抛出如下异常 django.db.utils.OperationalEr

解决:django.db.utils.OperationalError: unable to open database file

这是一个从GitHub上下载的,一个网站项目的源码.想要在自己的电脑上运行,期间过程相当曲折,不过至此终于是完成了. 1.安装过程: python2->virtualenv->django1.9.8 2.模块安装 pip install xadmin pip uninstall xadmin pip install django-simple-captcha pip install DjangoUeditor pip install Pillow 3.运行: python manage.py