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类型。
原文地址:https://www.cnblogs.com/love9527/p/9145009.html