詳解python中mongoengine庫用法

一、MongoDB的安裝與連接

安裝:pip install mongoengine

連接mongodb數據庫

from pymongo import MongoClient
cli = MongoClient('192.168.124.104', 27017)
mongodb = cli['test']
print(mongodb)
from mongoengine import connect
#  連接到User數據庫
connect('user', host='192.168.124.104', port=27017)

二、MongoEngine模型介紹

2.1、ODM模型介紹

from mongoengine import Document, StringField
class User(Document):
    email = StringField(required=True)
    first_name = StringField(max_length=50)
    last_name = StringField(max_length=50)

2.2、常見數據類型

 2.3、數據類型通用參數

  • db_field:文檔中的field/域/列名稱
  • required:是否為必填項
  • default:默認值
  • unique:唯一性約束
  • choices:可選擇的列表
  • primary_key:是否為文檔的主鍵,默認為False

2.4、類屬性meta常見配置項

類屬性,其配置項為python的dict(字典)

from mongoengine import Document, StringField
class User(Document):
    email = StringField(required=True)
    first_name = StringField(max_length=50)
    last_name = StringField(max_length=50)
    meta = {
    }

常見的配置項:

  • db_alias:指定文檔所在的數據庫(邏輯庫)
  • collection:指定文檔所在的集合
  • ordering:指定文檔的默認排序規則
  • indexes:指定文檔的索引規則

2.5、文檔的嵌套模型

學生信息數據字典

文檔的嵌套場景

情況一,數組-簡單數據類型:{'grades': [76, 51, 84]}

from mongoengine import Document, IntField, ListField
class Student(Document):
    grade = ListField(IntField())

情況二,單個文檔:{'grade': {'course_name': '語文', 'score': 76}}

from mongoengine import Document, StringField, IntField, ListField, EmbeddedDocument, EmbeddedDocumentField
#  自定義類型
class CourseGrade(EmbeddedDocument):
    course_name = StringField()
    score = IntField()
class Student(Document):
    grade = EmbeddedDocumentField(CourseGrade)

情況三,數組-文檔:{'grades': [{'score': 76}, {'score': 51}]}

from mongoengine import Document, IntField, ListField, EmbeddedDocument, EmbeddedDocumentField
#  自定義類型
class CourseGrade(EmbeddedDocument):
    score = IntField()
class Student(Document):
    grade = ListField(EmbeddedDocumentField(CourseGrade))

完整代碼:

from mongoengine import Document, connect, EnumField, StringField, IntField, ListField, EmbeddedDocument, \
    EmbeddedDocumentField
from enum import Enum
#  連接到User數據庫
connect('user', host='192.168.124.104', port=27017)
class SexEnum(Enum):
    MAN = '男'
    WOMAN = '女'
class CourseGrade(EmbeddedDocument):
    """成績信息(科目、老師、成績)-被嵌套的文檔"""
    course_name = StringField(max_length=64, required=True, verbose_name='科目')
    teacher = StringField(max_length=16, verbose_name='老師')
    score = IntField(min_value=0, max_value=150, required=True, verbose_name='成績')
    def __repr__(self):
        return f"CourseGrade({self.course_name},{self.score})"
    def __str__(self):
        return self.__repr__()
class Student(Document):
    """學生信息"""
    # verbose_name 自定義參數,用於顯示定義域的名稱
    stu_no = IntField(required=True, unique=True, verbose_name='學號')
    stu_name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性別')
    class_name = StringField(max_length=10, verbose_name='班級')
    address = StringField(max_length=255, verbose_name='傢庭住址')
    phone_no = StringField(max_length=11, verbose_name='電話號碼')
    age = IntField(min_value=0, max_value=150, verbose_name='年齡')
    grades = ListField(EmbeddedDocumentField(CourseGrade), verbose_name='成績數組')
    meta = {
        #  指定文檔的集合
        'collection': 'students',
        #  指定排序,可以指定多個域。例如:'age':根據年齡升序,'-age':根據年齡降序
        'ordering': ['-age']
    }
    def __repr__(self):
        return f'Grade({self.stu_no}, {self.stu_name})'
    def __str__(self):
        return self.__repr__()
class Grade(Document):
    """學生成績"""
    # verbose_name 自定義參數,用於顯示定義域的名稱
    stu_no = IntField(required=True, verbose_name="學號")
    stu_name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性別')
    class_name = StringField(max_length=10, verbose_name='班級')
    address = StringField(max_length=255, verbose_name='傢庭住址')
    phone_no = StringField(max_length=11, verbose_name='電話號碼')
    age = IntField(min_value=0, max_value=150, verbose_name='年齡')
    grade = EmbeddedDocumentField(CourseGrade, verbose_name='成績')
    meta = {
        # 指定文檔的集合
        'collection': 'grades',
        # 指定排序,可以指定多個域。例如:'age':根據年齡升序,'-age':根據年齡降序
        'ordering': ['-age']
    }
    def __repr__(self):
        return f'Grade({self.stu_no}, {self.stu_name})'
    def __str__(self):
        return self.__repr__()

 三、添加數據

添加數據一般有兩種方式:

3.1、方式一

一般步驟:

  • 第一步,構造ODM模型類對象:user=User(username='張三')
  • 第二步,驗證數據:user.validate()
  • 第三步,保存數據:user.save()

模型中的驗

  • 內置的驗證器,如max_length, min_value
  • 自定義驗證器

模型中自定義驗證方法示例代碼如下:

import re
from mongoengine import StringField
from mongoengine.errors import ValidationError
def phone_required(value):
    pattern = r'^1[0-9][10]$'
    if not re.search(pattern, value):
        raise ValidationError('請輸入正確的手機號')
phone_no = StringField(validation=phone_required)

方式一示例代碼:

import random
from model import Student, Grade, SexEnum, CourseGrade
class LearnMongoDBEngine(object):
 
    def __init__(self, info):
        self.info = info
        print(self.info)
 
    def add_one_student(self):
        """新增一個學生信息"""
        student = Student(
            stu_no=random.randint(3000, 9999999),
            stu_name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            class_name='六年級三班',
            address=self.info['address'],
            phone_no=self.info['phone'],
            age=random.randint(10, 15),
            grades=[
                CourseGrade(course_name='語文', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='數學', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='英語', teacher=self.info['teacher'], score=random.randint(1, 100)),
            ]
        )
        print(student, student.grades)
        result = student.save()
        return result
if __name__ == '__main__':
    info = {'name': '鐵扇公主', 'address': '北京市朝陽區', 'phone': '19121741234', 'teacher': '王老師'}
 
    obj = LearnMongoDBEngine(info)
    obj.add_one_student()

mongodb數據庫中插入的數據:

3.2、方式二:使用create()方法

User.objects.create(**kwargs)

示例代碼:

import random
from model import Student, Grade, SexEnum, CourseGrade
class LearnMongoDBEngine(object):
    def __init__(self, info):
        self.info = info
        print(self.info)
    def add_one_student(self):
        """新增一個學生信息"""
        result = Student.objects.create(
            stu_no=random.randint(3000, 9999999),
            stu_name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            class_name='六年級三班',
            address=self.info['address'],
            phone_no=self.info['phone'],
            age=random.randint(10, 15),
            grades=[
                CourseGrade(course_name='語文', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='數學', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='英語', teacher=self.info['teacher'], score=random.randint(1, 100)),
            ]
        )
        # student = Student(
        #     stu_no=random.randint(3000, 9999999),
        #     stu_name=self.info['name'],
        #     sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
        #     class_name='六年級三班',
        #     address=self.info['address'],
        #     phone_no=self.info['phone'],
        #     age=random.randint(10, 15),
        #     grades=[
        #         CourseGrade(course_name='語文', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #         CourseGrade(course_name='數學', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #         CourseGrade(course_name='英語', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #     ]
        # )
        print(result, result.grades)
        # result = student.save()
        return result
if __name__ == '__main__':
    info = {'name': '盧俊義', 'address': '上海市浦東新區', 'phone': '18721741234', 'teacher': '張老師'}
    obj = LearnMongoDBEngine(info)
    obj.add_one_student()

mongodb數據庫中插入的數據:

四、查詢數據

結果集QuerySet的獲取:User.objects,User是模型對象

常用的查詢方法:

  • all():查詢所有文檔
  • filter():按照條件查詢
  • count():滿足條件的文檔數
  • sum()/average():求和/求平均數
  • order_by():排序
  • .skip().limit():分頁

4.1、單個文檔查詢

  • first():沒有文檔則返回None,User.objects.first()
  • get(**kwargs)

多個文檔時,異常:MultipleObjectsReturned
沒有文檔時,異常:DoesNotExist
僅有一個文檔時:返回ODM對象

示例代碼:

from model import Student
class LearnMongoDBEngine(object):
    def get_one_student(self):
        """查詢一個學生的信息"""
        student_info = Student.objects.first()
        print(student_info, student_info.id, student_info.stu_name, student_info.address)
        return student_info
    def get_all_student(self):
        """查詢所有學生的信息"""
        student_all_info = Student.objects.all()
        print(student_all_info)
        return student_all_info
    def get_student_by_id(self, pk: str):
        """根據學生的id查詢"""
        student_info_id = Student.objects.get(id=pk)
        print(student_info_id)
        return student_info_id
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.get_one_student()
    obj.get_all_student()
    obj.get_student_by_id('62dcd1f1a0da9e5521e73223')

運行結果:

4.2、條件查詢

1)比較運算符

 在MongoEngine中使用雙下劃線(__)分割。比如:age__gt=12,表示年齡大於12的學生信息。

2)MongoEngine中的字符串查詢   【i表示不區分大小寫】

3)多個條件組合查詢

  • Q函數的使用:from mongoengine.queryset.visitor import Q
  • 多個條件同時滿足:Student.objects.filter(Q(key1=value1) & Q(key2=value2))
  • 多個條件部分滿足:Student.objects.filter(Q(key1=value1) | Q(key2=value2))
from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def get_one_student(self):
        """查詢一個學生的信息"""
        student_info = Student.objects.first()
        print(student_info, student_info.id, student_info.stu_name, student_info.address)
        return student_info
    def get_all_student(self):
        """查詢所有學生的信息"""
        student_all_info = Student.objects.all()
        print(student_all_info)
        return student_all_info
    def get_student_by_id(self, pk: str):
        """根據學生的id查詢"""
        student_info_id = Student.objects.get(id=pk)
        print(student_info_id)
        return student_info_id
    def get_student_1(self):
        """獲取大於12歲的學生信息"""
        result = Student.objects.filter(age__gt=12)
        print(result)
        return result
    def get_student_2(self):
        """獲取所有姓李的學生"""
        result = Student.objects.filter(stu_name__startswith='李')
        print(result)
        return result
    def get_student_3(self):
        """查詢年齡在9~12之間(含)的學生信息"""
        # SELECT * FROM school_student_info WHERE age BETWEEN 9 AND 12;
        # db.students.find({'age': {'$gte': 9, '$lte': 12}})
        result = Student.objects.filter(Q(age__gte=9) & Q(age__lte=12))
        print(result)
        return result
    def get_student_4(self):
        """查詢所有12歲以上的男生和9歲以下的女生"""
        result = Student.objects.filter(Q(age__gt=12, sex=SexEnum.MAN) | Q(age__lt=9, sex=SexEnum.WOMAN))
        print(result)
        return result
    def get_grade(self):
        """查詢大於等於60分的學生成績信息"""
        result = Student.objects.filter(grades__score__gte=80)  # 註意這兒寫法
        print(result)
        for i in result:
            print(i.grades)
        return result
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.get_one_student()
    obj.get_student_1()
    obj.get_student_2()
    obj.get_student_3()
    obj.get_student_4()
    obj.get_grade()

運行結果:  【註意:打印信息是由model中__call__函數設置決定的】

4.3、聚合統計

  • 滿足條件的文檔數:User.objects.count(),所有的結果集都可以使用
  • 求和/平均數:User.objects.filter().sum(field) / User.objects.filter().average(field)
from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def get_student_4(self):
        """查詢所有12歲以上的男生和9歲以下的女生"""
        result = Student.objects.filter(Q(age__gt=12, sex=SexEnum.MAN) | Q(age__lt=9, sex=SexEnum.WOMAN))
        print(result)
        return result
 
    def get_student_5(self):
        """查詢所有12歲以上的男生和9歲以下的女生總數"""
        result = Student.objects.filter(Q(age__gt=12, sex=SexEnum.MAN) | Q(age__lt=9, sex=SexEnum.WOMAN)).count()
        print(result)
        return result
 
    def get_man_sex(self):
        """統計性別為男的總人數,並求出其平均年齡和總年齡"""
        queryset = Student.objects.filter(sex='男')
        print(queryset)
        man_num_count = queryset.count()
        print(man_num_count)
        man_avg_age = queryset.average('age')
        print(man_avg_age)
        man_sum_age = queryset.sum('age')
        print(man_sum_age)
        return man_avg_age, man_sum_age
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.get_student_4()
    obj.get_student_5()
    obj.get_man_sex()

運行結果:

 4.4、排序

  • -:倒敘排列
  • (+):正序排序,默認就是正序
  • Student.objects().order_by('field1', '-field2')
from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def get_max_min_age(self):
        """獲取最大年齡和最小年齡的學生信息"""
        queryset_min_age = Student.objects.order_by('age').first()
        queryset_max_age = Student.objects.order_by('-age').first()
        print(queryset_min_age, queryset_min_age.age)
        print(queryset_max_age, queryset_max_age.age)
 
        return '200 OK'
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.get_max_min_age()

運行結果: 

 4.5、分頁處理

  • 方式一,切片方式:User.objects.all()[10:15]
  • 方式二,.skip().limit():User.objects.skip(10).limit(5)
from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def paginate(self, page: int = 1, page_size: int = 5):
        """
        分頁處理
        :param page: 當前是第幾頁
        :param page_size: 每頁有多少數據
        :return:
        """
        #  方法一:切片
        start = (page - 1) * page_size
        end = start + page_size
        queryset1 = Student.objects.all()[start:end]
        print(queryset1)
        #  方法二:skip().limit()
        queryset2 = Student.objects.skip(start).limit(page_size)
        print(queryset2)
        return "200 OK"
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.paginate(1, 6)
    print("*" * 100)
    obj.paginate(1, 3)
    obj.paginate(2, 3)

運行結果:

 五、修改和刪除數據

5.1、修改數據

修改數據時一般先過濾數據,再修改

  • 修改一條數據:User.objects.filter().update_one()
  • 批量修改數據:User.objects.filter().update()

from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def update_one(self):
        """修改一條數據"""
        queryset = Student.objects.filter(stu_no='2438197')
        print(queryset)
        result = queryset.update_one(stu_name='白龍馬', phone_no='16452412564')
        # result = queryset.update_one(stu_name='白龍馬', unset__phone_no=True)
        print(result)
    def update_one_2(self):
        """修改一條數據"""
        queryset = Student.objects.filter(stu_no=3152784).first()
        print(queryset)
        if queryset:
            queryset.stu_name = '沙和尚'
            result = queryset.save()
            print(result)
            return "200 OK"
        else:
            return "error"
    def update_many(self):
        """將年齡10歲的學生年齡加一歲"""
        queryset = Student.objects.filter(age=10)
        print(queryset)
        queryset.update(inc__age=1)
        print(queryset)
        return "200 OK"
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.update_one()
    obj.update_one_2()
    obj.update_many()

運行結果:

5.2、刪除數據

User.objects.filter().delete()

from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum
class LearnMongoDBEngine(object):
    def delete_data(self):
        """刪除年齡大於13歲的學生"""
        queryset_start = Student.objects.all()
        print(f"刪除前學生總數量:{queryset_start.count()}")
        queryset = Student.objects.filter(age__gt=13)
        print(f'刪除的學生的數量:{queryset.count()}')
        res = queryset.delete()
        print(f"刪除的結果:{res}")
        queryset_end = Student.objects.all()
        print(f"刪除後剩餘學生總數量:{queryset_end.count()}")
if __name__ == '__main__':
    obj = LearnMongoDBEngine()
    obj.delete_data()

運行結果:

附錄:

main.py 

import random
from mongoengine.queryset.visitor import Q
from model import Student, Grade, SexEnum, CourseGrade
class LearnMongoDBEngine(object):
    def __init__(self, info):
        self.info = info
        print(self.info)
    def add_one_student(self):
        """新增一個學生信息"""
        result = Student.objects.create(
            stu_no=random.randint(3000, 9999999),
            stu_name=self.info['name'],
            sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
            class_name='六年級三班',
            address=self.info['address'],
            phone_no=self.info['phone'],
            age=random.randint(10, 15),
            grades=[
                CourseGrade(course_name='語文', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='數學', teacher=self.info['teacher'], score=random.randint(1, 100)),
                CourseGrade(course_name='英語', teacher=self.info['teacher'], score=random.randint(1, 100)),
            ]
        )
        # student = Student(
        #     stu_no=random.randint(3000, 9999999),
        #     stu_name=self.info['name'],
        #     sex=random.choice([SexEnum.MAN, SexEnum.WOMAN]),
        #     class_name='六年級三班',
        #     address=self.info['address'],
        #     phone_no=self.info['phone'],
        #     age=random.randint(10, 15),
        #     grades=[
        #         CourseGrade(course_name='語文', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #         CourseGrade(course_name='數學', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #         CourseGrade(course_name='英語', teacher=self.info['teacher'], score=random.randint(1, 100)),
        #     ]
        # )
        print(result, result.grades)
        # result = student.save()
        return result
    def get_one_student(self):
        """查詢一個學生的信息"""
        student_info = Student.objects.first()
        print(student_info, student_info.id, student_info.stu_name, student_info.address)
        return student_info
    def get_all_student(self):
        """查詢所有學生的信息"""
        student_all_info = Student.objects.all()
        print(student_all_info)
        return student_all_info
    def get_student_by_id(self, pk: str):
        """根據學生的id查詢"""
        student_info_id = Student.objects.get(id=pk)
        print(student_info_id)
        return student_info_id
    def get_student_1(self):
        """獲取大於12歲的學生信息"""
        result = Student.objects.filter(age__gt=12)
        print(result)
        return result
    def get_student_2(self):
        """獲取所有姓李的學生"""
        result = Student.objects.filter(stu_name__startswith='李')
        print(result)
        return result
    def get_student_3(self):
        """查詢年齡在9~12之間(含)的學生信息"""
        # SELECT * FROM school_student_info WHERE age BETWEEN 9 AND 12;
        # db.students.find({'age': {'$gte': 9, '$lte': 12}})
        result = Student.objects.filter(Q(age__gte=9) & Q(age__lte=12))
        print(result)
        return result
    def get_student_4(self):
        """查詢所有12歲以上的男生和9歲以下的女生"""
        result = Student.objects.filter(Q(age__gt=12, sex=SexEnum.MAN) | Q(age__lt=9, sex=SexEnum.WOMAN))
        print(result)
        return result
    def get_student_5(self):
        """查詢所有12歲以上的男生和9歲以下的女生總數"""
        result = Student.objects.filter(Q(age__gt=12, sex=SexEnum.MAN) | Q(age__lt=9, sex=SexEnum.WOMAN)).count()
        print(result)
        return result
    def get_man_sex(self):
        """統計性別為男的總人數,並求出其平均年齡和總年齡"""
        queryset = Student.objects.filter(sex='男')
        print(queryset)
        man_num_count = queryset.count()
        print(man_num_count)
        man_avg_age = queryset.average('age')
        print(man_avg_age)
        man_sum_age = queryset.sum('age')
        print(man_sum_age)
        return man_avg_age, man_sum_age
    def get_grade(self):
        """查詢大於等於60分的學生成績信息"""
        result = Student.objects.filter(grades__score__gte=80)  # 註意這兒寫法
        print(result)
        for i in result:
            print(i.grades)
        return result
    def get_max_min_age(self):
        """獲取最大年齡和最小年齡的學生信息"""
        queryset_min_age = Student.objects.order_by('age').first()
        queryset_max_age = Student.objects.order_by('-age').first()
        print(queryset_min_age, queryset_min_age.age)
        print(queryset_max_age, queryset_max_age.age)
        return '200 OK'
    def paginate(self, page: int = 1, page_size: int = 5):
        """
        分頁處理
        :param page: 當前是第幾頁
        :param page_size: 每頁有多少數據
        :return:
        """
        #  方法一:切片
        start = (page - 1) * page_size
        end = start + page_size
        queryset1 = Student.objects.all()[start:end]
        print(queryset1)
        #  方法二:skip().limit()
        queryset2 = Student.objects.skip(start).limit(page_size)
        print(queryset2)
        return "200 OK"
    def update_one(self):
        """修改一條數據"""
        queryset = Student.objects.filter(stu_no='2438197')
        print(queryset)
        result = queryset.update_one(stu_name='白龍馬', phone_no='16452412564')
        # result = queryset.update_one(stu_name='白龍馬', unset__phone_no=True)
        print(result)
    def update_one_2(self):
        """修改一條數據"""
        queryset = Student.objects.filter(stu_no=3152784).first()
        print(queryset)
        if queryset:
            queryset.stu_name = '沙和尚'
            result = queryset.save()
            print(result)
            return "200 OK"
        else:
            return "error"
    def update_many(self):
        """將年齡10歲的學生年齡加一歲"""
        queryset = Student.objects.filter(age=10)
        print(queryset)
        queryset.update(inc__age=1)
        print(queryset)
        return "200 OK"
    def delete_data(self):
        """刪除年齡大於13歲的學生"""
        queryset_start = Student.objects.all()
        print(f"刪除前學生總數量:{queryset_start.count()}")
        queryset = Student.objects.filter(age__gt=13)
        print(f'刪除的學生的數量:{queryset.count()}')
        res = queryset.delete()
        print(f"刪除的結果:{res}")
        queryset_end = Student.objects.all()
        print(f"刪除後剩餘學生總數量:{queryset_end.count()}")
if __name__ == '__main__':
    #  自我測試代碼
    pass

model.py

from mongoengine import Document, connect, EnumField, StringField, IntField, ListField, EmbeddedDocument, \
    EmbeddedDocumentField
from enum import Enum
#  連接到User數據庫
connect('user', host='192.168.124.104', port=27017)
class SexEnum(Enum):
    MAN = '男'
    WOMAN = '女'
class CourseGrade(EmbeddedDocument):
    """成績信息(科目、老師、成績)-被嵌套的文檔"""
    course_name = StringField(max_length=64, required=True, verbose_name='科目')
    teacher = StringField(max_length=16, verbose_name='老師')
    score = IntField(min_value=0, max_value=150, required=True, verbose_name='成績')
    def __repr__(self):
        return f"CourseGrade({self.course_name},{self.score})"
    def __str__(self):
        return self.__repr__()
class Student(Document):
    """學生信息"""
    # verbose_name 自定義參數,用於顯示定義域的名稱
    stu_no = IntField(required=True, unique=True, verbose_name='學號')
    stu_name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性別')
    class_name = StringField(max_length=10, verbose_name='班級')
    address = StringField(max_length=255, verbose_name='傢庭住址')
    phone_no = StringField(max_length=11, verbose_name='電話號碼')
    age = IntField(min_value=0, max_value=150, verbose_name='年齡')
    grades = ListField(EmbeddedDocumentField(CourseGrade), verbose_name='成績數組')
    meta = {
        #  指定文檔的集合
        'collection': 'students',
        #  指定排序,可以指定多個域。例如:'age':根據年齡升序,'-age':根據年齡降序
        'ordering': ['-age'],
        'strict': False  # 設置非嚴格校驗字段則不需要吧所有字段都聲明
    }
    def __repr__(self):
        return f'Grade({self.stu_no}, {self.stu_name})'
    def __str__(self):
        return self.__repr__()
class Grade(Document):
    """學生成績"""
    # verbose_name 自定義參數,用於顯示定義域的名稱
    stu_no = IntField(required=True, verbose_name="學號")
    stu_name = StringField(required=True, max_length=16, verbose_name='姓名')
    sex = EnumField(enum=SexEnum, verbose_name='性別')
    class_name = StringField(max_length=10, verbose_name='班級')
    address = StringField(max_length=255, verbose_name='傢庭住址')
    phone_no = StringField(max_length=11, verbose_name='電話號碼')
    age = IntField(min_value=0, max_value=150, verbose_name='年齡')
    grades = EmbeddedDocumentField(CourseGrade, verbose_name='成績')
    meta = {
        # 指定文檔的集合
        'collection': 'grades',
        # 指定排序,可以指定多個域。例如:'age':根據年齡升序,'-age':根據年齡降序
        'ordering': ['-age']
    }
    def __repr__(self):
        return f'Grade({self.stu_no}, {self.stu_name})'
    def __str__(self):
        return self.__repr__()

官方文檔:
 https://docs.mongoengine.org/guide/querying.html

到此這篇關於python中mongoengine庫用法詳解的文章就介紹到這瞭,更多相關python mongoengine庫內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: