Django query JSONField where the value is equal to {} - django

I have a model with a JSONField like this:
metadata = JSONField(
_('Metadata'),
blank=True,
default=dict,
help_text=_('Multi key-value field to hold any additional information'),
)
Is there any way in Django to query for objects where metadata is equal to {}? I use Django 2.1.

Simply try this
MyModel.objects.filter(metadata={})
Reference: Querying JSONField in Django

Related

How to add list field in the django restframework sqlite

how to add list field in the sqlite db in django restframework
camera = models.ForeignKey(Camera, on_delete=models.CASCADE)
updated_time = models.DateTimeField(auto_now_add=True)
objects_inself = models.????
SQLite doesn't support list or array fields, but you have few options depending on what you want to archive.
Switch to Postresql (it supports those fields)
If your list store objects, then you can create model for the objects and create One-to-Many or Many-to-Many relationship. Then you can get a list of models using something like YourModel.your_related_objects_set.all()
If you want to just store simple values like integers or strings then you can use Charfield and some custom logic to extract values from string and convert it to list

Django models: How do I check that a decorartor property exists

I have a Profile model with a decorator property
#property
def primary_phone(self):
When I query for the primary phone for a given id like this it works
x = Profile.objects.get(id=3)
x.primary_phone
outputs
Out[3]: '+256771000022'
However filtering for the same like this
Profile.objects.filter(primary_phone="+256771000022").exists()
outputs
FieldError: Cannot resolve keyword 'primary_phone' into field. Choices are: _created_at, _modified_at, apierror, business,...)
#porperty is a managed python attribute https://docs.python.org/3/library/functions.html#property and can not be queried through DB because its data is not part of the DB.
Use a django model field if you need to query it or use Python to handle this attribute after querying the DB.

Do data conversion after Django model object is fetched

I want to save the python dictionary inside the Django model as JSON and I want to convert that JSON back into a python dictionary when that data is fetched.
I know I can do it inside view but I want to implement it in the model so it can return dictionary object when queried.
is there any signal or any post_fetch method that I can use to achieve it, I couldn't find anything googling it...
You might want to look into simply using the Python JSON package, unless you are using Postgres as your database - in which case JSONField is the way to go. The json package is explained here and you could use it in a model like so if I understand what you are saying:
import json
class MyModel(models.Model):
json_field = models.TextField() # or you can use JSONField if using Postgres
#property
def get_json_field_as_dictionary(self):
return json.loads(self.json_field)
def set_json_field(self, mydict):
self.json_field = json.dumps(mydict)
#classmethod
def get_json_from_dictionary(cls, mydict):
return json.dumps(mydict)
When you are saving to the database, you can use json.dumps(myDictionary) or convert the dictionary to JSON by calling MyModelObject.set_json_field(myDictionary) to convert a Python dictionary to JSON and then store it in the json_field of the model. To retrieve the JSON data as a dictionary, you simply call MyModel.objects.last().get_json_field_as_dictionary (or whatever you prefer to call it, json_dictionary perhaps so it would be MyModel.objects.last().json_dictionary) and it will return the value of that property as if it were an element in the model without having to do the conversion each time.
Or, if you are using Postgres as your backend, this is a lot easier with JSONField:
class MyModel(models.Model):
json_field = models.JSONField(null=True)
And to save:
myObject = myModel.objects.create(json_field=myDictionary)
If you clarify I can update my answer to explain better.
You may want to use JSONField. It allows storing data encoded as JSON and retrieve them as the corresponding Python data type, including dictionary.
JSONField only works on PostgreSQL with Django < 3.1, but works on any database with Django >= 3.1.

Django Postgresql ArrayField aggregation

In my Django application, using Postgresql, I have a model with an ArrayField of CharFields.
I would like to know if there's a DB way to aggregate and get a list of all the strings in the table. For example:
['dog', 'cat']
['dog']
['cat']
would yield ['dog', 'cat']
I know how to do that in Python but would like to find out a way to aggregate this on the DB level.
Using Django 1.8.4
In PostgreSQL you can do the following:
SELECT DISTINCT UNNEST(array_column) FROM the_table;
So if your model looks something like
class TheModel(models.Model):
# ...
array_field = ArrayField(models.CharField(max_length=255, blank=True),\
default=list)
# ...
the Django equivalent is:
from django.db.models import Func, F
TheModel.objects.annotate(arr_els=Func(F('array_field'), function='unnest'))\
.values_list('arr_els', flat=True).distinct()

How to implement JsonField in django that has postgresql as backend?

I want to implement JsonField in my django application running postgresql.Can I also have indexing on that Json Field so that I can have Mongo like features? Do I have to make use of sqlalchemy for this or django built-in ORM is suitable for this purpose?
Thanks.
You can easily install django-jsonfield
pip install jsonfield
and use it on your field
class MyModel(models.Model):
my_json_field = JSONField()
It's just a TextField that serializes the json object to a python dictionary so no you can't have an index on it nor can you make queries against your json field.
If you are using Postgres (and don't care about compatibility with other DB engines) you should consider django's postgres fields
https://docs.djangoproject.com/en/1.9/ref/contrib/postgres/fields/
this should have much better performance than the ordinary jsonfield.
If DB compatibility is an issue and/or you want your field be readable/editable through django admin you might want to consider KeyValueField instead https://github.com/rewardz/django_model_helpers
Data is stored in DB like this
Name = abc
Age = 123
but returned to you like this
{"Name": "abc", "Age": "123"}
So if you make db_index = True you can do field__contains="Age = 123" but despite using db_index, its not fool proof because Age=1234 will also be returned by that query plus indexing text field is not usually recommended