• Django 2.0 学习(14):Django ORM 数据库操作(上)


    Django ORM 数据库操作(上)

    ORM介绍

    映射关系:
    数据库表名 ---------->类名;数据库字段 ---------->类属性;数据库表一行数据 ---------->类实例化对象;
    ORM两大功能:
    操作表:创建、修改、删除表;
    操作数据:增删改查;
    ORM利用pymysql第三方工具连接数据库,Django无法帮助我们创建数据库,只能我们创建完成后告诉它,让Django去连接;

    创建表之前的准备工作

    1.自己创建数据库;
    2.在settings.py文件中配置mysql数据库连接,sqlite3改为mysql:

    # 修改django默认sqlite3数据库为mysql
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'mydatabase',
            'USER': 'mydatabaseuser',
            'PASSWORD': 'mypassword',
            'HOST': '127.0.0.1',
            'PORT': '3306',
        }
    }
    

    修改project中的__init__.py文件,设置Django默认连接MySQL的方式:

    import pymysql
    pymysql.install_as_MySQLdb()
    

    3.创建数据库表
    打开models.py文件,写入如下代码:

    class Question(models.Model):
        question_text = models.CharField(max_length=200)
        pub_date = models.DateTimeField('date published')
        models.DateField()
    
        def __str__(self):
            return self.question_text
    

    执行命令创建

    python manage.py makemigrations        创建脚本
    python manage.py migrate        数据迁移
    

    4.查看数据库的sql语句(家在settings.py文件中)

    # 查看数据库执行代码
    LOGGING = {
        'version': 1,
        'disable_existing_loggers': False,
        'handlers': {
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',
            },
        },
        'loggers': {
            'django.db.backends': {
                'handlers': ['console'],
                'propagate': True,
                'level': 'DEBUG',
            },
        }
    }
    

    多对多的正反向查询

    在models.py文件中的模型如下:

    class Class(models.Model):
        name = models.CharField(max_length=32, verbose_name='班级名称')
        course = models.CharField(max_length=32, verbose_name='课程')
    
        def __str__(self):
            return self.name
    
    
    class Teacher(models.Model):
        name = models.CharField(max_length=32, verbose_name='姓名')
        classes = models.ManyToManyField(verbose_name='所属班级', to='Class')
        
        def __str__(self):
            return self.name
    

    题目1:查找吴老师所带班级

            # 方式一:基于对象的查找
            obj = models.Teacher.objects.filter(name="吴老师").first()
            print(obj.classes.all())
            print("吴老师带的班级",obj.classes.values("name"))
    
            # 方式二:基于双下划线的查找
            obj_cls = models.Teacher.objects.filter(name="吴老师").values("classes__name")
            print("吴老师带的班级",obj_cls)
    

    注意:查询单个的时候用.values或者value_list,不要用obj.classes.name,这样查询到的会是None,反向查询也是如此,不管是一对多,还是多对多,查询多的一方就用.all()方法
    运行结果(非此例结果):

    表结构:

    # 一个学生有一个班级,每个班级有好多学生,所以是多对一的关系,关联字放在多的一方
    class Student(models.Model):
        name = models.CharField(max_length=32, verbose_name='姓名')
        age = models.IntegerField(verbose_name='年龄')
        classes = models.ForeignKey(verbose_name='所属班级', to='Class')
        
        def __str__(self):
            return self.name
    
    
    class Class(models.Model):
        name = models.CharField(max_length=32, verbose_name='班级名称')
        course = models.CharField(max_length=32, verbose_name='课程')
    
        def __str__(self):
            return self.name
    
    
    class Teacher(models.Model):
        name = models.CharField(max_length=32, verbose_name='姓名')
        classes = models.ManyToManyField(verbose_name='所属班级', to='Class')
    
        def __str__(self):
            return self.name
    

    题目2.陈凡在哪个班级

    # 方式一:
    print("陈凡所在班级:", models.Student.objects.filter(name="陈凡").values("classes__name")
    
    # 方式二:
    obj_class = models.Student.objects.filter(name="陈凡").first()
    print("陈凡所在班级:", obj_class.classes.name)
    

    题目3.查询陈凡所在班级的老师姓名

    print("陈凡所在班级老师的姓名:", models.Student.objects.filter(name="陈凡").values("classes__teacher__name)
    

    题目4.查询高三2班所有学生姓名

    print("高三2班所有学生姓名", models.Class.object.filter(name="高三2班").values("student__name")
    
    object_class = models.Class.object.filter(name="高三2班").first()
    print("高三2班所有学生姓名", object_class.student_set.all().values("name"))
    # print("高三2班所有学生姓名", object_class.student_set.name)        这样打印的结果是None
    

    重要知识点

    form表单中要用submit,如果用button切记要加上type,不然button默认的type是submit,会有影响:

    <button type="button" onclick="doValidation();">提交</button>
    <input type="button" onclick="doValidation();" value="提交" />
    // 上面两种写法是对的,功能一样
    
    <button onclick="doValidation();">提交</button>
    // 如果写成这种,默认为submit。本来doValidation方法里有提交功能了,再加上按钮也是提交功能,会提交两次。所以使用按钮时最好指定type类型。
    
  • 相关阅读:
    小程序--获取手机型号
    小程序---换行
    小程序 页面禁止左右上下滑动
    小程序---数据列表 隔行变色
    小程序 视频播放出来的坑
    小程序-----上传图片
    小程序---提交成功弹框
    小程序——Tab切换
    接收请求参数及数据回显
    重定向与转发
  • 原文地址:https://www.cnblogs.com/love9527/p/9145009.html
Copyright © 2020-2023  润新知