在 Django 中创建自定义字段查找
如何在 Django 中创建自定义字段查找 ?
过滤查询集时,django 提供了一组可以使用的查找:__contains
、__iexact
、__in
等。我希望能够为我的经理提供新的查找,因此,例如,有人可能会说:
twentysomethings = Person.objects.filter(age__within5=25)
取回年龄在 20 到 30 岁之间的所有 Person
对象。我是否需要将其子类化QuerySet
或 Manager
类来执行此操作?它将如何实施?
How do you create custom field lookups in Django?
When filtering querysets, django provides a set of lookups that you can use: __contains
, __iexact
, __in
, and so forth. I want to be able to provide a new lookup for my manager, so for instance, someone could say:
twentysomethings = Person.objects.filter(age__within5=25)
and get back all the Person
objects with an age between 20 and 30. Do I need to subclass the QuerySet
or Manager
class to do this? How would it be implemented?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最佳实践不是创建字段查找,而是创建一个管理器方法,它可能看起来有点像这样:
然后用法如下:
Rather than creating a field lookup, best practice would be to create a manager method, that might look a little bit like this:
then usage would be like so:
首先,我要说的是,没有适当的 Django 机制来公开促进你想要的东西。
(编辑 - 实际上从 Django 1.7 开始就有: https://docs .djangoproject.com/en/1.7/howto/custom-lookups/ )
也就是说,如果你真的想要完成这个,子类
QuerySet
并重写_filter_or_exclude()
方法。然后创建一个自定义管理器,仅返回您的自定义QuerySet
(或猴子补丁Django的QuerySet
,恶心)。我们在 neo4django 中执行此操作,以便在构建特定于 Neo4j 的同时重用尽可能多的 Django ORM 查询集代码代码>查询对象。尝试(大致)类似这样的事情,改编自扎克的答案。我已经将字段查找解析的实际错误处理作为读者的练习:)
最后的评论 - 显然,如果您想链接自定义字段查找,这将变得非常棘手。另外,我通常会写得更实用一些,并使用 itertools 来提高性能,但我认为将其省略会更清楚。玩得开心!
First, let me say that there is no Django machinery in place that's meant to publicly facilitate what you'd like.
(Edit - actually since Django 1.7 there is: https://docs.djangoproject.com/en/1.7/howto/custom-lookups/ )
That said, if you really want to accomplish this, subclass
QuerySet
and override the_filter_or_exclude()
method. Then create a custom manager that only returns your customQuerySet
(or monkey-patch Django'sQuerySet
, yuck). We do this in neo4django to reuse as much of the Django ORM queryset code as possible while building Neo4j-specificQuery
objects.Try something (roughly) like this, adapted from Zach's answer. I've left actual error handling for the field lookup parsing as an exercise for the reader :)
Final remarks - clearly, if you want to chain custom field lookups, this is going to get pretty hairy. Also, I'd normally write this a bit more functionally and use itertools for performance, but thought it was more clear to leave it out. Have fun!
从 Django 1.7 开始,有一个简单的方法来实现它。您的示例实际上与 文档 中的示例非常相似
:注册时,您只需使用
Field.register_lookup(AbsoluteValueLessThan)
即可。As of Django 1.7, there is a simple way to implement it. Your example is actually very similar to the one from the documentation:
While registering, you can just use
Field.register_lookup(AbsoluteValueLessThan)
instead.更灵活的方法是编写自定义查询集和自定义管理器。使用 ozan 的代码:
这允许您链接自定义查询。所以这两个查询都是有效的:
A more flexible way to do this is to write a custom QuerySet as well as a custom manager. Working from ozan's code:
This allows you to chain your custom query. So both these queries would be valid: