Reputation: 5664
I'm working on a Project using Python(3), Django(1.11) and DRF in which I have to filter the data on the base of a json
object field which is saved as JSONFIELD
in db model.
Here's what I have tried:
# model.py
from django.db import models
import jsonfield
class MyModel(models.Model):
id = models.CharField(primary_key=True, max_length=255)
type = models.CharField(max_length=255)
props = jsonfield.JSONField()
repo = jsonfield.JSONField()
created_at = models.DateTimeField()
# serializers.py
class MyModelSerializer(serializers.ModelSerializer):
props = serializers.JSONField()
repo = serializers.JSONField()
class Meta:
model = EventModel
fields = "__all__"
# JSON object
{
"id":4633249595,
"type":"PushEvent",
"props":{
"id":4276597,
"login":"iholloway",
"avatar_url":"https://avatars.com/4276597"
},
"repo":{
"id":269910,
"name":"iholloway/aperiam-consectetur",
"url":"https://github.com/iholloway/aperiam-consectetur"
},
"created_at":"2016-04-18 00:13:31"
}
# views.py
class PropsEvents(generics.RetrieveAPIView):
serializer_class = MyModelSerializer
def get_object(self):
print(self.request.parser_context['kwargs']['id'])
queryset = MyModel.objects.filter(data__props__id=self.request.parser_context['kwargs']['id'])
obj = get_object_or_404(queryset)
return obj
It should return the MyModel records by
props ID
and should be able to return the JSON array of all theMyModel objects
where theprops ID
by the GET request at/mymodel/props/<ID>
. If the requestedprops
does not exist then HTTP response code should be 404, otherwise, the response code should be 200. The JSON array should be sorted in ascending order by MyModel ID.
When I sent a request to this view, it returns an error:
> django.core.exceptions.FieldError: Unsupported lookup 'id' for JSONField or join on the field not permitted.
> [18/Feb/2019 10:37:39] "GET /events/actors/2790311/ HTTP/1.1" 500 16210
So, how can I filter the objects based on the id of props
?
Help me, please! Thanks in advance!
Upvotes: 0
Views: 2732
Reputation: 1304
The feature your are looking for is possible, unfortunately it is not that straightforward. As far as I know it is not supported by the jsonfield
package, but instead you would have to use Postgres as your database backend and use its internal JSONField. I think you can choose one of the following:
django.contrib.postgres.fields.JSONField
and use Postgres as your db backend in all enviroments (and then support such lookups)class MyModel(models.Model):
id = models.CharField(primary_key=True, max_length=255)
type = models.CharField(max_length=255)
props = jsonfield.JSONField()
props_id = models.IntegerField(null=True)
repo = jsonfield.JSONField()
repo_id = models.IntegerField(null=True)
created_at = models.DateTimeField()
And then set the id values manually or in the save()
of the model:
def save(self, *args, **kwargs):
self.repo_id = self.repo.get("id")
self.props_id = self.props.get("id")
return super().save(*args, **kwargs)
Upvotes: 3
Reputation: 1986
You should use
from django.contrib.postgres.fields import JSONField
Instead of
import jsonfield
And after that I think everything should work correctly
Upvotes: 0