ORM操作
- 数据库数据类型:数字、字符串、时间、二进制,无布尔值
ORM分类
db first
	(1)先登录数据库,通过命令创建表结构及对应关系,
	(2)再通过工具连接上数据库,通过点操作,通过表结构生成类,不用写sql语句
code first(主流)
	通过类创建数据库,即转成sql数据,执行create
	(1)先写类
	(2)通过类,创建表结构
	例如:Django
- 使用场景
- 根据类自动创建数据库表
- 根据类对数据库中的数据,进行各种操作
 
创建数据库表结构流程
- 
写类 app02中的models.py # 创建的数据库表单名:app02_userinfo class UserInfo(models.Model): # 默认创建ID列,自增, 主键 # 用户名列,字符串类型,指定长度 username = models.CharField(max_length=32) #字符长度 password = models.CharField(max_length=64)
- 
注册app 工程中的settings.py INSTALLED_APPS中添加app命令,例如 INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘app02‘, ]
- 
根据情况配置使用数据库 默认数据库(无需修改) DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.sqlite3‘, ‘NAME‘: os.path.join(BASE_DIR, ‘db.sqlite3‘), } } 修改数据库方式,数据名(dbname)需要自己创建 DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘:‘dbname‘, ‘USER‘: ‘root‘, ‘PASSWORD‘: ‘xxx‘, ‘HOST‘: ‘‘, ‘PORT‘: ‘‘, } } 注:Django默认使用MySQLdb模块连接mysql数据库,但python 3.x中无该模块 需要改为pymysql:在project同名文件夹下的__init__.py文件中添加代码如下: import pymysql pymysql.install_as_MySQLdb()
- 
执行命令,生成表结构 - python manage.py makemigrations
- python manage.py migrate
 
基本操作
- 
增 方式一: models.UserInfo.objects.create(username=‘root‘, password=‘123‘) 方式二: dict_user = {‘username‘: ‘Lucy‘, ‘password‘: ‘123‘} models.UserInfo.objects.create(**dict_user) 方式三: obj = models.UserInfo(username=‘Tom‘, password=‘123‘) obj.save()
- 
删 models.UserInfo.objects.filter(username=‘Tom‘).delete() models.UserInfo.objects.filter(id=1).delete() models.UserInfo.objects.all().delete()
- 
改 models.UserInfo.objects.all().update(password=999) models.UserInfo.objects.filter(id=7).update(password=666)
- 
查 - 
单表 select * from tb where id>1 # 对应关系 modles.tb.objects.filter(id__gt=1) #id>1 modles.tb.objects.filter(id=1) modles.tb.objects.filter(id__lt=1) # id<1 modles.tb.objects.filter(id__gte=1) # id>=1 modles.tb.objects.filter(id__lte=1) # id<=1 # result的类型是QuerySet,是Django提供的,类似列表 # 全部 result = models.UserInfo.objects.all() # 查看sql语句 print(result.query) # 过滤全部满足条件的 result = models.UserInfo.objects.filter(username=‘Tom‘) for item in result: print(item.id, item.username, item.password) # 取第一个元素,没有为None obj1 = models.UserInfo.objects.filter(username="root", password="999").first() # 仅获取一条信息,但id不存在,会报错 models.UserInfo.objects.get(id=nid) # 统计个数 obj2 = models.UserInfo.objects.filter(username="root", password="999").count() # QuerySet类型,元素是对象 v1 = models.Business.objects.all() # QuerySet类型,元素是字典 v2 = models.Business.objects.all().values(‘id‘, ‘name‘) # QuerySet类型,元素是元组 v3 = models.Business.objects.all().values_list(‘id‘, ‘name‘)
- 
跨表 - 
点操作 - 应用场景:获取到QuerySet对象后的操作
 
- 
双下划线操作 - 应用场景:在获取QuerSet对象前的操作,及写在models.Host.objects.xxx 上
 QuerySet类型,元素是对象,跨表通过点方式v1 = models.Host.objects.all() print(v1[0].nid, v1[0].port, v1[0].b_id, v1[0].b.name) QuerySet类型,元素是字典,跨表通过双下划线v2 = models.Host.objects.all().values(‘hostname‘, ‘b__name‘) print(v2[0][‘hostname‘], v2[0][‘b__name‘]) QuerySet类型,元素是元组v3 = models.Host.objects.all().values_list(‘nid‘, ‘hostname‘, ‘b_id‘, ‘b__name‘) for row in v3: print(row[0], row[1], row[2], row[3]) 
 
- 
 
- 
操作表结构
- 
修改表结构 (1)username = models.CharField(max_length=32) 修改为 username = models.CharField(max_length=64) (2)再执行以下两条命令,重新生成表结构 - python manage.py makemigrations
- python manage.py migrate
 注:改小会存在数据丢失风险 
- 
添加表结构 方式一: (1)email = models.CharField(max_length=64) (2)python manage.py makemigrations 选择1,输入默认值 (3)python manage.py migrate 方式二:(指定默认为NULL) (1)gender = models.CharField(max_length=64, null=True) (2)python manage.py makemigrations (3)python manage.py migrate 方式三:(指定默认值) (1)name_en = models.CharField(max_length=64, default=‘RDD‘) (2)python manage.py makemigrations (3)python manage.py migrate
- 
删除表结构 (1)# gender = models.CharField(max_length=64, null=True) (2)python manage.py makemigrations (3)python manage.py migrate
字段类型
- 
数据库常见类型:字符串、数字、时间、二进制 
- 
EmailField、URLField、GenericIPAddressField等类型 - 本质:字符串
- Django特有
- 例如: email = models.EmailField(max_length=64)
- 用途:Django后台管理时,使用,检测数据合法性
 
- 
AutoField类型,用于自增 - uid = models.AutoField(primary_key=True)
 
字段参数
null               -> db是否可以为空
default            -> 默认值
primary_key        -> 主键
db_column          -> 列名
db_index           -> 索引
unique			   -> 唯一索引
unique_for_date   	数据库中字段【日期】部分是否可以建立唯一索引
unique_for_month	数据库中字段【月】部分是否可以建立唯一索引
unique_for_year		数据库中字段【年】部分是否可以建立唯一索引
auto_now_add        -> 创建时,自动生成时间
	例如 
		app的views.py
			def login(request):
				models.UserGroup.objects.create(caption="monitor")
		app的models.py
			class UserGroup(models.Model):
			    uid = models.AutoField(primary_key=True)
			    caption = models.CharField(max_length=32)
			    ctime = models.DateTimeField(auto_now_add=True, null=True)
				uptime = models.DateTimeField(auto_now=True, null=True)
auto_now       -> 更新时,自动更新为当前时间
	例如:
		app的models.py
			uptime = models.DateTimeField(auto_now=True, null=True)
		app的views.py
			# 这种方式不支持
			obj = UserGroup.objects.filter(id=1).update(caption=‘CEO‘) 
			# 这种方式:OK
			obj = models.UserGroup.objects.filter(uid=1).first()
			obj.caption = "CEO"
			obj.save()
	
choices			  -> django admin中显示下拉框,避免连表查询
	例如:
	app的models.py
		class UserInfo(models.Model):
		    # 默认创建ID列,自增, 主键
		    # 用户名列,字符串类型,指定长度
		    # 字符串、数字、时间、二进制
		    username = models.CharField(max_length=64)
		    password = models.CharField(max_length=64)
		    email = models.EmailField(max_length=64, null=True)
		    user_type_choices = (
		        (1, "超级用户"),
		        (2, "管理员"),
		        (3, "普通用户"),
		    )
		    user_type_id = models.IntegerField(choices=user_type_choices, default=3)
blank             -> django admin是否可以为空
verbose_name      -> django admin显示字段中文
editable          -> django admin是否可以被编辑
error_messages    -> 错误信息欠
help_text         -> django admin提示
validators		  -> django form ,自定义错误信息(欠)
