简体   繁体   中英

Filter Django queryset for a dict value

I have a queryset of Products with JSONField attributes containing dict

class Product(models.Model):
attributes = JSONField(
    pgettext_lazy('Product field', 'attributes'),
    encoder=DjangoJSONEncoder, default={})

I want to filter Products where attributes['12'] == '31'

Following one works:

qs.filter(attributes__contains={'12': '31'})

Following one does not:

qs.filter(attributes__12='31') Is this something I can achieve with PostgreSQL or should I move it to ES?

EDIT: Unfortunately I cannot use first solution, as this dict may contain more keys.

First solution works well. Given we have:

product.attributes = {'333': ['6', '1']}

We can filter it out by:

Product.objects.filter(attributes__contains={'333': ['6']}

etc. Totally overlooked it.

You should be able to use the second format, ie qs.filter(attributes__key='value') .

Your issue in this case, as explained in the docs , is that when using an integer as a key in a JSON query, that key will be used as the index of an array, thus it's interpreted as attributes[12] instead of attributes['12'] .

As long as you stick to string keys, you should be fine.

An example:

class MyModel(models.Model)
    json = JSONField(default=dict)


p = MyModel.objects.create(json={'0': 'something', 'a': 'something else'})

MyModel.objects.filter(json__0='something') # returns empty queryset
MyModel.objects.filter(json__a='something else') # returns the object created above

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM