Development of django - configuration and use of mongodb

Keywords: Python MongoDB JSON Database Django

Today, I sorted out how to use mongodb in django project. The environment is as follows:
ubuntu18.04, django2.0.5, drf3.9, mongoengine0.16

Step 1: configure mongodb and mysql in settings.py as follows (you can use both mysql and mongodb):

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',   # database engine
        'NAME': 'django_test2',                  # The name of the database you want to store data in, you need to create it in advance
        'USER': 'root',                         # Database user name
        'PASSWORD': 'wyzane',                     # Password
        'HOST': 'localhost',                    # Host
        'PORT': '3306',                         # Port used by the database
    },
    'mongotest': {
        'ENGINE': None,
    }
}

import mongoengine
# Connect to the database named mongotest5 in mongodb
conn = mongoengine.connect("mongotest")

Step 2: insert data into mongodb
1. Insert json type data

models.py:
    import mongoengine
    class StudentModel(mongoengine.Document):
        name = mongoengine.StringField(max_length=32)
        age = mongoengine.IntField()
        password = mongoengine.StringField(max_length=32)

views.py:
    from rest_framework.views import APIView
    class FirstMongoView(APIView):
        def post(self, request):
            name = request.data["name"]
            age = request.data["age"]
            password = request.data["password"]
            StudentModel.objects.create(name=name, age=age, password=password)
            return Response(dict(msg="OK", code=10000))

Insert data in the format:

{
    "name": "nihao",
    "age": 18,
    "password": "123456"
}

2. Insert json data with list

models.py:
    import mongoengine
    class Student2Model(mongoengine.Document):
        name = mongoengine.StringField(max_length=32)
        # Used to store data of type list
        score = mongoengine.ListField()

views.py:
    from rest_framework.views import APIView
    class FirstMongo2View(APIView):
        def post(self, request):
            name = request.data["name"]
            score = request.data["score"]
            Student2Model.objects.create(name=name, score=score)
            return Response(dict(msg="OK", code=10000))

Insert data in the format:

{
     "name": "test",
     "score": [12, 13]
}

3. Insert complex json data with dict and list

models.py:
    import mongoengine
    class Student3Model(mongoengine.Document):
        name = mongoengine.StringField(max_length=32)
        # DictField is used to store data of dictionary type
        score = mongoengine.DictField()
views.py:
    from rest_framework.views import APIView
    class FirstMongo3View(APIView):
        def post(self, request):
            name = request.data["name"]
            score = request.data["score"]
            Student3Model.objects.create(name=name, score=score)
            return Response(dict(msg="OK", code=10000))

Insert data in the format:

{
    "name": "test",
    "score": {"xiaoming": 12, "xiaoli": 13}
}
Or:
{
    "name": "test",
    "score": {"xiaoming": 12, "xiaoli": {"xiaozhao": 14}}
}
Or:
{
"name": "test",
"score": {"xiaoming": 12, "xiaoli": {"xiaozhao": {"xiaoliu": 12, "xiaojian": 18}}}
}
Or:
{
"name": "test",
"score": {"xiaoming": 12, "xiaoli": {"xiaozhao": {"xiaoliu": 12, "xiaojian": [12,13,14]}}}
}

Step 3: query the data in mongodb
1. Query and sequence complex json data

serializers.py:
    class StudentSerializer(serializers.Serializer):
        name = serializers.CharField()
        score = serializers.DictField()  # Serializing complex json data
        # DictField is similar to EmbeddedDocumentField, but more flexible than EmbeddedDocumentField
views.py:
    class FirstMongo4View(APIView):
        def get(self, request):
            student_info = Student3Model.objects.all()
            # Add filter conditions
            # student_info = Student3Model.objects.filter(name="test1")
            ser = StudentSerializer(instance=student_info, many=True)
            return Response(dict(msg="OK", code="10000", data=ser.data))

2. Serialize two document s with nesting relationship in mongodb

models.py:
    class AuthorModel(mongoengine.EmbeddedDocument):
        author_name = mongoengine.StringField(max_length=32)
        age = mongoengine.IntField()


    class BookModel(mongoengine.Document):
        book_name = mongoengine.StringField(max_length=64)
        publish = mongoengine.DateTimeField(default=datetime.datetime.utcnow())
        words = mongoengine.IntField()
        author = mongoengine.EmbeddedDocumentField(AuthorModel)

serializers.py: Attention and rest_framework In serialization of DictField()Difference
    from rest_framework_mongoengine import serializers as s1
    class AuthorSerializer(s1.DocumentSerializer):  
        # DocumentSerializer inherits from ModelSerializer in drf and is used to serialize document s in mongodb instead of ModelSerializer
        # You can check the details on the official website
        class Meta:
            model = AuthorModel
            fields = ('author_name', 'age')


    class BookSerializer(s1.DocumentSerializer):
        author = AuthorSerializer()

        class Meta:
            model = BookModel
            fields = ('book_name', 'publish', 'words', 'author')

    AuthorSerializer You can write like this:
    class AuthorSerializer(s1.EmbeddedDocumentSerializer):
        # EmbeddedDocumentSerializer inherits DocumentSerializer
        class Meta:
            model = AuthorModel
            fields = ('author_name', 'age')

views.py:
    class BookView(APIView):
        def get(self, request):
            """
            //Query data
            :param request:
            :return:
            """
            books = BookModel.objects.all()
            ser = BookSerializer(instance=books, many=True)
            return Response(dict(msg="OK", code="10000", data=ser.data))

When serializing the two associated tables in mongodb, if the Serializer inherits from the Serializer and ModelSerializer in rest framework, the following exception will be thrown:

Django serialization to JSON error: 'MetaDict' object has no attribute 'concrete_model'

At this time, the serializer needs to inherit from the rest framework mongoengine class. For details, see the official website:
http://umutbozkurt.github.io/...

I'll talk about it today. If you have any questions, welcome to exchange.

Posted by nimbus on Sat, 07 Dec 2019 05:53:20 -0800