django基于动态property的查询()
我想知道是否有一种方法可以使用 property()
动态生成的 python 属性在查询集上使用 Django 的 filter() 。我有每个用户的 first_name
和 last_name
,我想根据他们的串联名称 first_name last_name
进行过滤。 (这背后的原因是,当我执行自动完成时,我会搜索查询是否与名字、姓氏或连接的一部分匹配。我希望 John S
匹配 John Smith<例如,
我创建了 name
的属性:
def _get_name(self):
return self.first_name + " " + self.last_name
name = property(_get_name)
名称。
这样我可以调用 user.name
来获取连接的 code>User.objects.filter(name__istartswith=query) 我收到错误 无法将关键字“name”解析到字段中
关于如何执行此操作的任何想法?数据库中的字段存储全名?
I was wondering if there was a way to use Django's filter() on query sets using a dynamically generated python property using property()
. I have first_name
and last_name
of every user, and I want to filter based on their concatenated name first_name last_name
. (The reason behind this is that when I do autocomplete I search to see if the query matches first name, last name, or part of the concatenation. I want John S
to match John Smith
, for example.
I created a property of name
:
def _get_name(self):
return self.first_name + " " + self.last_name
name = property(_get_name)
This way I can call user.name
to get the concatenated name.
However, if I try to do User.objects.filter(name__istartswith=query)
I get the error Cannot resolve keyword 'name' into field.
Any ideas on how to do this? Do I have to create another field in the database to store the full name?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
接受的答案并不完全正确。
在许多情况下,您可以在模型管理器中重写
get()
以从关键字参数中pop
动态属性,然后将要查询的实际属性添加到 < code>kwargs 关键字参数字典。请务必返回super
,以便任何常规get()
调用都会返回预期结果。我只是粘贴我自己的解决方案,但对于 __startswith 和其他条件查询,您可以添加一些逻辑来
分割
双下划线并进行适当处理。这是我的解决方法,允许通过动态属性进行查询:
在 models.py 中:
在 utils.py 中(为了上下文):
The accepted answer is not entirely true.
For many cases, you can override
get()
in the model manager topop
dynamic properties from the keyword arguments, then add the actual attributes you want to query against into thekwargs
keyword arguments dictionary. Be sure to return asuper
so any regularget()
calls return the expected result.I'm only pasting my own solution, but for the
__startswith
and other conditional queries you could add some logic tosplit
the double-underscore and handle appropriately.Here was my work-around to allow querying by a dynamic property:
In models.py:
In utils.py (for the sake of context):
认为在 django 中不可能过滤不作为数据库字段出现的属性,但是您可以执行以下操作来进行很酷的自动完成搜索:
此代码为系统的用户提供了开始输入名字的灵活性或姓氏,用户将感谢您允许这样做。
Think it's not possible in django to filter on properties that does not present as a database filed, but what you can do to make cool autocomplete search is something like this:
This code gives the user of your system a flexibility to start typing either first name or last name and the user will be thankful to you for allowing this.
filter()
在数据库级别运行(它实际上编写 SQL),因此不可能将它用于基于您的 python 代码的任何查询(问题中的动态属性)
。这是本部门许多其他答案汇总的答案:)
filter()
operates on the database level (it actually writes SQL), so it won't be possible to use it for any queries based on your python code(dynamic property in your question)
.This is an answer put together from many other answers in this department : )
我有类似的问题,正在寻找解决方案。理所当然地认为搜索引擎是最好的选择(例如
django-haystack
和Elasticsearch
),这就是我仅使用 Django ORM 实现一些满足您需求的代码的方式(您可以将icontains
替换为istartswith
):在我的例子中,我不知道用户是否会插入 '
first_name
last_name< /code>' 或反之亦然,所以我使用了以下代码。
对于 Django <1.8,您可能需要使用 SQL
CONCAT
函数来使用extra
,如下所示:I had a similar problem and was looking for solution. Taking for granted that a search engine would be the best option (e.g.
django-haystack
withElasticsearch
), that's how I would implement some code for your needs using only the Django ORM (you can replaceicontains
withistartswith
):In my case I didn't know whether the user would insert '
first_name
last_name
' or viceversa, so I used the following code.With Django <1.8, you would probably need to resort to
extra
with the SQLCONCAT
function, something like the following: