按属性过滤

2025-02-10 08:57:00
admin
原创
57
摘要:问题描述:是否可以通过模型属性过滤 Django 查询集?我的模型中有一个方法:@property def myproperty(self): [..] 现在我想通过这个属性进行过滤,例如:MyModel.objects.filter(myproperty=[..]) 这可能吗?解决方案 1:不是。D...

问题描述:

是否可以通过模型属性过滤 Django 查询集?

我的模型中有一个方法:

@property
def myproperty(self):
    [..]

现在我想通过这个属性进行过滤,例如:

MyModel.objects.filter(myproperty=[..])

这可能吗?


解决方案 1:

不是。Django 过滤器在数据库级别运行,生成 SQL。要根据 Python 属性进行过滤,您必须将对象加载到 Python 中以评估该属性——此时,您已经完成了加载它的所有工作。

解决方案 2:

我可能误解了你最初的问题,但是python 中有一个内置过滤器。

filtered = filter(myproperty, MyModel.objects)

但最好使用列表推导:

filtered = [x for x in MyModel.objects if x.myproperty()]

甚至更好,一个生成器表达式:

filtered = (x for x in MyModel.objects if x.myproperty())

解决方案 3:

借鉴@TheGrimmScientist 建议的解决方法,您可以通过在 Manager 或 QuerySet 上定义这些“sql 属性”,然后重用/链接/组合它们:

与经理:

class CompanyManager(models.Manager):
    def with_chairs_needed(self):
        return self.annotate(chairs_needed=F('num_employees') - F('num_chairs'))

class Company(models.Model):
    # ...
    objects = CompanyManager()

Company.objects.with_chairs_needed().filter(chairs_needed__lt=4)

使用查询集:

class CompanyQuerySet(models.QuerySet):
    def many_employees(self, n=50):
        return self.filter(num_employees__gte=n)

    def needs_fewer_chairs_than(self, n=5):
        return self.with_chairs_needed().filter(chairs_needed__lt=n)

    def with_chairs_needed(self):
        return self.annotate(chairs_needed=F('num_employees') - F('num_chairs'))

class Company(models.Model):
    # ...
    objects = CompanyQuerySet.as_manager()

Company.objects.needs_fewer_chairs_than(4).many_employees()

更多信息请参阅https://docs.djangoproject.com/en/1.9/topics/db/managers/。请注意,我没有参考文档,也没有测试上述内容。

解决方案 4:

看起来使用带有注释的 F()将是我的解决方案。

它不会按 进行过滤@property,因为F在将对象带入 python 之前会与数据库进行对话。但仍然将其作为答案放在这里,因为我想要按属性进行过滤的原因实际上是想根据两个不同字段的简单算术结果来过滤对象。

因此,大致如下:

companies = Company.objects\n    .annotate(chairs_needed=F('num_employees') - F('num_chairs'))\n    .filter(chairs_needed__lt=4)

而不是将属性定义为:

@property
def chairs_needed(self):
    return self.num_employees - self.num_chairs

然后对所有对象进行列表理解。

解决方案 5:

我遇到了同样的问题,并且我开发了这个简单的解决方案:

objects = [
    my_object 
    for my_object in MyModel.objects.all() 
    if my_object.myProperty == [...]
]

这不是一个高性能的解决方案,它不应该在包含大量数据的表中完成。这对于简单的解决方案或个人小项目来说很棒。

解决方案 6:

请有人纠正我,但我想我已经找到了解决方案,至少对我自己的情况而言。

我想要研究所有那些属性完全等于...无论什么的元素。

但是我有多个模型,这个例程应该适用于所有模型。并且它确实如此:

def selectByProperties(modelType, specify):
    clause = "SELECT * from %s" % modelType._meta.db_table

    if len(specify) > 0:
        clause += " WHERE "
        for field, eqvalue in specify.items():
            clause += "%s = '%s' AND " % (field, eqvalue)
        clause = clause [:-5]  # remove last AND

    print clause
    return modelType.objects.raw(clause)

使用这个通用子程序,我可以选择所有与我的“指定”(属性名称,属性值)组合词典完全相等的元素。

第一个参数采用(models.Model),

第二个字典如下: {“property1”:“77”,“property2”:“12”}

它会创建一个 SQL 语句

SELECT * from appname_modelname WHERE property1 = '77' AND property2 = '12'

并返回这些元素的查询集 (QuerySet)。

这是一个测试功能:

from myApp.models import myModel

def testSelectByProperties ():

    specify = {"property1" : "77" , "property2" : "12"}
    subset = selectByProperties(myModel, specify)

    nameField = "property0"
    ## checking if that is what I expected:
    for i in subset:
        print i.__dict__[nameField], 
        for j in specify.keys():
             print i.__dict__[j], 
        print 

然后呢?你觉得怎么样?

解决方案 7:

我知道这是一个老问题,但是为了那些跳到这里的人,我认为阅读下面的问题和相关答案是有用的:

如何在 Django 1.4 中自定义管理过滤器

解决方案 8:

还可以使用重复属性 get/set-logic 的查询集注释,例如@rattray和@thegrimmscientist所建议的,与 结合使用property这可以产生在 Python 级别数据库级别都有效的东西。

但不确定其缺点:请参阅这个 SO 问题作为示例。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1590  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1361  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   18  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   18  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   19  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用