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?

udo
  • 4,832
  • 4
  • 54
  • 82
Albert
  • 2,146
  • 10
  • 32
  • 54
  • 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 – Lemayzeur Apr 27 '18 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']}")` – Albert Apr 27 '18 at 13:20
  • why you don't use [jsonfield](https://docs.djangoproject.com/en/2.0/ref/contrib/postgres/fields/#jsonfield) in the model ? – Brown Bear Apr 27 '18 at 13:22

1 Answers1

1

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')
Lemayzeur
  • 8,297
  • 3
  • 23
  • 50
  • 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. – Albert Apr 27 '18 at 14:49
  • Here's the error I keep getting `bson.errors.InvalidDocument: Cannot encode object: ` Do you have any ideas what could cause it? – Albert Apr 27 '18 at 15:15