如何编写查询以获取django中json字段中的查找值

sha*_*nks 17 django django-models django-queryset

我的数据库中有一个json字段就像

jsonfield = {'username':'chingo','reputation':'5'}
Run Code Online (Sandbox Code Playgroud)

我如何编写查询,以便我可以找到是否存在用户名.就像是

username = 'chingo'
query = User.objects.get(jsonfield['username']=username)
Run Code Online (Sandbox Code Playgroud)

我知道上面的查询是错误的,但我想知道是否有办法访问它?

bwv*_*549 20

如果您使用的是django-jsonfield包,那么这很简单.假设您有这样的模型:

from jsonfield import JSONField
class User(models.Model):
    jsonfield = JSONField()
Run Code Online (Sandbox Code Playgroud)

然后,要搜索具有特定用户名的记录,您可以这样做:

User.objects.get(jsonfield__contains={'username':username})
Run Code Online (Sandbox Code Playgroud)

  • 你可以使用`User.objects.get(jsonfield__contains ='"username":"{}"'.format(username))` (2认同)

okm*_*okm 12

这种用法有些反模式.此外,它的实现不具有常规性能,并且可能容易出错.
通常在需要查看字段时不要使用jsonfield.正如Daniel指出的那样,使用RDBMS提供的方式或MongoDB(内部以更快的BSON运行).

由于JSON格式确定性,你可以通过使用contains(regex在处理w/multiple '\'甚至更慢时有问题)来实现它,我不认为username以这种方式使用是好的,所以请name改用:

def make_cond(name, value):
    from django.utils import simplejson 
    cond = simplejson.dumps({name:value})[1:-1] # remove '{' and '}'
    return ' ' + cond # avoid '\"'

User.objects.get(jsonfield__contains=make_cond(name, value))
Run Code Online (Sandbox Code Playgroud)

它的工作时间一样长

  • jsonfield使用相同的转储实用程序(在simplejson这里)
  • name而且value 不是太特别(我到目前为止还不知道任何一个例子,也许有人可以指出来)
  • 你的jsonfield数据没有损坏(虽然不太可能)

实际上我正在编写一个可编辑的jsonfield并考虑是否支持这样的操作.负面证据如上所述,感觉就像是一些黑魔法,好吧.


fre*_*ees 12

从Django 1.9开始,您就可以使用PostgreSQL的原生JSONField.这使得搜索JSON非常简单.在您的示例中,此查询将起作用:

User.objects.get(jsonfield__username='chingo')
Run Code Online (Sandbox Code Playgroud)

如果您有较旧版本的Django,或者您使用Django JSONField库与MySQL或类似的东西兼容,您仍然可以执行查询.

在后一种情况下,jsonfield将被存储为文本字段并在进入Django时映射到dict.在数据库中,您的数据将像这样存储

{"username":"chingo","reputation":"5"}
Run Code Online (Sandbox Code Playgroud)

因此,您只需搜索文本即可.您在此过程中的查询将是:

User.objects.get(jsonfield__contains='"username":"chingo"')
Run Code Online (Sandbox Code Playgroud)


Cha*_*yer 7

2019 年:正如@freethebees 指出的那样,现在很简单:

User.objects.get(jsonfield__username='chingo')
Run Code Online (Sandbox Code Playgroud)

但是正如文档示例中提到的,您可以深入查询,如果 json 是一个数组,您可以使用一个整数来索引它:

https://docs.djangoproject.com/en/2.2/ref/contrib/postgres/fields/#querying-jsonfield

>>> Dog.objects.create(name='Rufus', data={
...     'breed': 'labrador',
...     'owner': {
...         'name': 'Bob',
...         'other_pets': [{
...             'name': 'Fishy',
...         }],
...     },
... })
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})

>>> Dog.objects.filter(data__breed='collie')
<QuerySet [<Dog: Meg>]>

>>> Dog.objects.filter(data__owner__name='Bob')
<QuerySet [<Dog: Rufus>]>

>>> Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
<QuerySet [<Dog: Rufus>]>
Run Code Online (Sandbox Code Playgroud)

尽管这是针对 postgres 的,但我相信它在其他数据库(如 MySQL)中的工作原理相同