Django之ORM数据库操作
一、 ORM介绍
映射关系:
表名->类名
字段->属性
表记录->类实例化对象
ORM的两大功能:
操作表:
- 创建表
- 修改表
- 删除表
操作数据行:
- 增删改查
ORM利用pymysql第三方工具链接数据库
Django没有办法帮助我们创建数据库,只能我们自己创建好,让Django去链接。
二、 创建表之前的准备
1) 自己创建数据库
2) 在settings里面配置mysql数据库连接(默认为sqllit3)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 链接数据库的类型
'NAME': 'db', # 链接数据库的名字
'HOST': '127.0.0.1', # 数据库主机地址
'PORT': 3306, # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': '123456', # 数据库密码
}
}
注意:
这样写上是会报错的,因为Django通过ORM操作数据默认是用的MySQLdb模块(python2中的),那么我们需要改设置。
在app(应用)文件夹中的__init__.py问文件中加入下面两行:
import pymysql
pymysql.install_as_MySQLdb()
三、 创建数据库表
models.py
from django.db import models
# Create your models here.
class Book(models.Model): #必须要继承的
nid = models.AutoField(primary_key=True) #自增id(可以不写,默认会有自增id)
title = models.CharField(max_length=32)
publishDdata = models.DateField() #出版日期
author = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2) #一共5位,保留两位小数
执行创建命令:(必须记住)
- python3 manage.py makemigrations 创建脚本(会存到qpp目录下的migrations文件夹中)
- python3 manage.py migrate 迁移
四、 查看数据库的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',
},
}
}
五、 一些小知识
1) 多对多的正反向查询
class Class(models.Model):
name= models.CharField(max_length=32,verbose_name="班级名")
course = models.CharField(verbose_name="课程",max_length=32)
def __str__(self):
return self.name
class Teacher(models.Model):
name= models.CharField(max_length=23,verbose_name="姓名")
classes = models.ManyToManyField(verbose_name="所属班级",to="Class")
def __str__(self):
return self.name
查找登登所带的班级
# 方式一:基于对象的查找
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)
注意:要说明的是多对多的查询用.all,,查单个的时候用.values或者values_list,不要用obj.classes.name,,这样查到的会是None,反向查询也是如此。我就是犯了这样的错,引以为戒。。
总结:不管是一对多,还是多对多,要是查询多得一方就得用all()
2) 例子
- 表结构
from django.db import models
# Create your models here.
# 一个学生有一个班级,一个班级可以有好多学生,所以是
# 一对多的关系,关联字段放在多的一方
class Student(models.Model):
name = models.CharField(max_length=32,verbose_name="姓名")
age = models.IntegerField(verbose_name="年龄")
classes = models.ForeignKey(to="Class",verbose_name="所属班级")
def __str__(self):
return self.name
class Class(models.Model):
name = models.CharField(max_length=32,verbose_name="班级名")
course = models.CharField(verbose_name="课程",max_length=32)
def __str__(self):
return self.name
class Teacher(models.Model):
name = models.CharField(max_length=23,verbose_name="姓名")
classes = models.ManyToManyField(verbose_name="所属班级",to="Class")
def __str__(self):
return self.name
问题:
- 查询海燕所在哪个班级
- # 方式一:
- print("海燕所在的班级",models.Student.objects.filter(name="海燕").values("classes__name"))
- # 方式二:
- obj_cls = models.Student.objects.filter(name="海燕").first()
- print("海燕所在的班级",obj_cls.classes.name)
- 查询海燕所在班的老师的姓名
print("海燕所在班的老师的姓名",models.Student.objects.filter(name="海燕").values("classes__teacher__name"))
- 查询软件1班的所有学生的姓名
- print("软件1班的所有学生的姓名",models.Class.objects.filter(name="软件1班").values("student__name"))
- obj = models.Class.objects.filter(name="软件1班").first()
- # print("软件测试1班的所有学生的姓名",obj.student_set.name) #这样打印的结果是None
- print("软件1班的所有学生的姓名",obj.student_set.all().values("name"))
重点
1、form表单中要用submit,如果用button切记要加上type,不然button默认的type是submit,会有影响
<button class="login" type="button">注册</button>
<button type="button" onclick="doValidation();">提交</button>
<input type="button" onclick="doValidation();" value="提交"/>
上面两种写法是对的,功能一样。
<button onclick="doValidation();">提交</button>
如果写成这种,默认为submit,本来doValidation方法里有提交功能了,
再加上按钮也是提交功能,会提交两次。所以使用按钮时最好指定type类型。