0

So I'm using django rest framework on top of django as my serverside and MongoDB as a database (a mongo replica set, to be specific).

My model looks like this:

#models.py

class MyModel(models.Model):
    data = models.TextField()

Here's the serializer that I'm using:

#serializers.py

class MySerializer(serializers.ModelSerializer):
    data = serializers.JSONField(binary=True)

    def create(self, validated_data):
        test = MyModel(data=validated_data)
        test.save()
        return test

    class Meta:
        model = MyModel
        fields = ['data']

This is my view:

#views.py

class MyView(APIView):
    serializer_class = MySerializer

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        try:
            serializer.is_valid(raise_exception=True)
            serializer.save()
        except djongo.sql2mongo.SQLDecodeError:
            return Response(
                status=status.HTTP_503_SERVICE_UNAVAILABLE
            )

        return Response(
            status=status.HTTP_200_OK
        )

Then, in a test mode, I make a few records into the database using httpie. The requests look like this:

http POST localhost:8000/api/test data='{"sizes": ["M", "L"], "colors": ["white", "yellow"], "model": "poet"}'

http POST localhost:8000/api/test data='{"colors": ["red", "black"], "sizes": ["S", "M"], "model": "polo", "material": "silk"}'

http POST localhost:8000/api/test data='{"colors": ["white", "yellow"], "sizes": ["M", "L", "XL"], "model": "poet", "material": "bamboo"}'

The data is written to the DB and replicated. So now I would want to make the following query:

test = MyModel.objects.filter(data__contains={'sizes': ['M', 'L']})

But it returns an empty queryset and it's not supposed to.

What am I doing wrong?

3
  • the field data is TextField, even though it contains data that look like json or dict, it is not. test = MyModel.objects.filter(data__icontains="{'sizes': ['M', 'L']}") filter data as string, inside quotes Commented Apr 27, 2018 at 13:09
  • I understand that and that's what I don't like, but is there anyway of making a full-blown JSONField in the model? I would like to make queries like that MyModel.objects.filter(data__icontains="{'sizes': ['M', 'L']}") Commented Apr 27, 2018 at 13:20
  • why you don't use jsonfield in the model ? Commented Apr 27, 2018 at 13:22

1 Answer 1

0

According to the Django documentation here:

I think this is what you are looking for (untested)

Model

class MyModel(models.Model):
    data = models.JSONField() # New in Django 1.11.

query

# data='{"sizes": ["M", "L"], "colors": ["white", "yellow"], "model": "poet"}'
MyModel.objects.filter(data__sizes__contains=['M', 'L'])
MyModel.objects.filter(data__model='poet')
Sign up to request clarification or add additional context in comments.

2 Comments

hm and is it possible to use it with MongoDB? I remember trying and it didn't work, I'm trying to do this at the moment and am getting an error.
Here's the error I keep getting bson.errors.InvalidDocument: Cannot encode object: <django.contrib.postgres.fields.jsonb.JsonAdapter object at 0x7fd998f7a898> Do you have any ideas what could cause it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.