表数据操作简介
表数据操作主要包含对数据和表的增删改查,表类型有单表,一对多类型表和多对多类型表。
创建表数据
表数据 | 代指 |
---|---|
类名 | 生成数据库表名 |
类中models.字段类型 | 生成数据库字段 |
models.OneToOneField | 一对一 |
models.ForeignKey | 一对多表 |
models.ManyToManyField | 多对多表 |
OneToOneField()参数
OneToOneField(ForeignKey)
to, # 要进行关联的表名
to_field=None # 要关联的表中的字段名称
on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为
###### 对于一对一 ######
# 1. 一对一其实就是 一对多 + 唯一索引
# 2.当两个类之间有继承关系时,默认会创建一个一对一字段
# 如下会在A表中额外增加一个c_ptr_id列且唯一:
class C(models.Model):
nid = models.AutoField(primary_key=True)
part = models.CharField(max_length=12)
class A(C):
id = models.AutoField(primary_key=True)
code = models.CharField(max_length=1)
ForeignKey()参数
ForeignKey(ForeignObject) # ForeignObject(RelatedField)
to, # 要进行关联的表名
to_field=None, # 要关联的表中的字段名称
on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为
- models.CASCADE,删除关联数据,与之关联也删除
- models.DO_NOTHING,删除关联数据,引发错误IntegrityError
- models.PROTECT,删除关联数据,引发错误ProtectedError
- models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
- models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
- models.SET,删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
def func():
return 10
class MyModel(models.Model):
user = models.ForeignKey(
to="User",
to_field="id"
on_delete=models.SET(func),)
related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件:
# 如:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}
from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
db_constraint=True # 是否在数据库中创建外键约束
parent_link=False # 在Admin中是否显示关联数据
ManyToManyField()参数
ManyToManyField(RelatedField)
to, # 要进行关联的表名
related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件:
# 如:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}
from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
symmetrical=None, # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
# 做如下操作时,不同的symmetrical会有不同的可选字段
models.BB.objects.filter(...)
# 可选字段有:code, id, m1
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=True)
# 可选字段有: bb, code, id, m1
class BB(models.Model):
code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=False)
through=None, # 自定义第三张表时,使用字段用于指定关系表
through_fields=None, # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('group', 'person'),
)
class Membership(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
inviter = models.ForeignKey(
Person,
on_delete=models.CASCADE,
related_name="membership_invites",
)
invite_reason = models.CharField(max_length=64)
db_constraint=True, # 是否在数据库中创建外键约束
db_table=None, # 默认创建第三张表时,数据库中表的名称
表数据获取
类型 | 获取方式 |
---|---|
[obj,obj]对象 | .all,.filter |
[{},{}]字典 | .values |
[(),()]元组 | .vlaues_list |
多数据获取用列表形式表示,比如select标签单选获取为$().val(1),多选为$.val([1,2,3])
数据库中表对象数据获取
需要获取的数据=表对象.表字段名
如:
peo_obj = models.Table.objects.last() #获取表最后一行数据的对象
peo_id = peo_obj.id #获取表数据对象中的id字段值
创建表
models.py
注:不设置id字段列默认自动添加
from 应用名 import models
class 类名(models.Model):
id=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID') #创建主键,自增长、设置主键、无序列号设置、别名为ID
字段1=models.CharField("字段1",max_length=20) #创建字符串字段,最大长度为20,别名为【字段1】
字段2=models.IntegerField(verbose_name='字段2') #创建整型字段,别名为【字段2】
setting.py
INSTALLED_APPS = [应用名]
创建生成表
python manage.py makemigrations 应用名
python manage.py migrate
反向创建数据库表
反向创建数据库表(一般用于配置连接好数据库,数据库中已经有数据,但项目中没有models表的已有环境)
python manage.py inspectdb
创建后导出并替代models.py,默认生成路径是项目根目录而不是APP根目录
python manage.py inspectdb > models.py
models 数据操作
增加
在views.py中添加视图函数,要提前引用视图models类
from 应用名.models import 类名 #引入视图数据库models类
方法一(实例类的对象):
def 函数名(request):
model对象=类名(字段1="值1",字段2="值2") #根据字段添加值
model对象.save() #保存到数据库
return 返回值
方法二(调用create方法):
def 函数名(request):
类名.objects.create(字段1="值1",字段2="值2") #根据字段添加值,并同步到数据库
return 返回值
字典传输数据增加数据
def 函数名(request):
类名.objects.create(**kwargs) #字典形式传输和添加,字典键对应数据库字段
return 返回值
删除
调用filter方法查找并删除
def 函数名(request):
类名.objects.filter(查找字段名="值").delete()
return 返回值
修改
方法一:(实例对象重新赋值)
def 函数名(request):
model对象=类名.objects.get(查找字段名="值") #获取数据对象集合
model对象.修改字段名="值" #修改字段值
model对象.save() #保存到数据库
方法二:(调用filter方法查找并重新赋值)
def 函数名(request):
models.类名[表名].objects.filter(查找字段名="值").update(要修改的字段名="修改后值") #查询指定字段所在行,给该行要修改的字段从新赋值
return 返回值
查询
查询方法
def 函数名(request):
model对象集合=类名.objects.方法(条件) #查询条件是可选项,比如使用模糊查询
model对象=model对象集合[0] #查询条件对象集合特定的对象
对象对应值=model对象.字段名 #查询对象对应的值
return 返回值
方法 | 释义 |
---|---|
filter(**kwargs) | 查找内容,值可以是(字段=”值”)也可以泛指字典,包含了与所给筛选条件相匹配的对象 |
all() | 显示所有内容,括号内可使用切片,如:all([:3])、all([::2])等 |
get(**kwargs) | 返回与所给筛选相匹配的结果,结果只有一个,若没有结果或超过一个抛出异常 |
values(*field) | 返回一个ValueQuerySet,一个特殊的QuerySet,运行后并不是一系列model的实例化对象,而是一个可迭代的字典序列 |
values_list(*field) | 返回一个ValueQuerySet,一个特殊的QuerySet,运行后并不是一系列model的实例化对象,而是一个元组序列 |
exclude(**kwargs) | 包含了与所给筛选条件不匹配的对象 |
order_by(*field) | 对查询结果排序 |
reverse() | 对查询结果反向排序 |
distinct() | 从反向结果中剔除重复记录 |
count() | 返回数据库中匹配查询(QuerySet)的对象数量 |
first() | 返回第一条记录 |
last() | 返回最后一条记录 |
exists() | 如果QuerySet包含数据,返回True,否则返回False |
查询结果运算
函数 | 释义 |
---|---|
Avg(“字段名”) | 平均值 |
Sum(“字段名”) | 求和 |
Max(“字段名”) | 求最大值 |
Min(“字段名”) | 最小值 |
示例
from django.db.models import Avg,Sum,Max,Min
models.表名.objects.all().aggregate(Sum('计算的字段'))
模糊查询
类名.objects.filter(查询条件)
查询条件 | 释义 |
---|---|
字段= | 等于 |
字段__exact= | 精准查询 |
字段__gt= | 大于 |
字段__gte= | 大于等于 |
字段__contains= | 模糊匹配(区分大小写) |
字段__icontains= | 模糊匹配(不区分大小写) |
字段__in= | 包含icontains |
字段__isnull= | 是否为空 |
字段__lt= | 小于 |
字段__lte= | 小于等于 |
字段__range= | 范围 |
执行原生SQL语句
from django.db import connection
def my_custom_sql(self):
with connection.cursor() as cursor:
cursor.execute("执行sql语句",)
#查出一条数据
row = cursor.fetchone()
#查出所有数据
#row = cursor.fetchall()
return row
综合示例
示例所用方法较少,可根据示例环境自行测试各个方法
架构
Mydiango
APP
migrations
0001_initial.py
__init_.py
templates
__init__.py
index.html
admin.py
apps.py
models.py
tests.py
views.py
Mydiango
settings.py
urls.py
wsgi.py
manage.py
创建项目和APP
django-admin startproject Mydjango
cd Mydjango
python manage.py startapp APP
示例配置
setting
INSTALLED_APPS 添加APP[以前存在的勿删]
'APP',
MYSQL配置数据库连接
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydata',
'USER': 'mydata',
'PASSWORD': 'Abc123',
'HOST': '192.168.88.80',
'POST': '3306',
}
}
SQLService配置数据库连接
DATABASES = {
'default': {
'NAME': 'screen',
'ENGINE': 'sql_server.pyodbc',
'HOST': '127.0.0.1',
'PORT': '1433',
'USER': 'user',
'PASSWORD': 'password',
'OPTIONS':{
'driver':'SQL Server Native Client 10.0',
}
}
}
TEMPLATES 添加静态文件存放目录路径[以前存在的勿删]
'DIRS': [os.path.join(BASE_DIR, 'APP/templates')],
init.py
在项目全局设置 Mydjango -> Mydjango -> __init__.py 中设置使用pymysql连接数据库
import pymysql
pymysql.install_as_MySQLdb()
urls.py
# coding=utf8
from django.contrib import admin
from django.urls import path,re_path
from APP import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path('^$',views.Index),
path('add/', views.Add_data), # url【add】添加 --- 对应 ---- 添加视图函数【Add_data】
path('delete/', views.Del_data), # url【delete】删除 --- 对应 ---- 删除视图函数【Del_data】
path('update/', views.Up_data), # url【update】更新 --- 对应 ---- 更新视图函数【Up_data】
path('select/', views.Sel_data), # url【select】查询 --- 对应 ---- 查询视图函数【Sel_data】
]
views.py
# -*- coding:utf8 -*-
from django.shortcuts import render,HttpResponse
import datetime
from APP.models import Animal_Table
def Index(request): #网站默认首页
return render(request,"index.html",locals())
def Add_data(request): #添加数据函数
Animal_Table.objects.create(Type="森林",Name="松鼠",Li_ID=1) # 根据字段添加值,并同步到数据库
Animal_Table.objects.create(Type="森林",Name="老虎",Li_ID=1)
Animal_Table.objects.create(Type="海洋",Name="鲸鱼",Li_ID=2)
Animal_Table.objects.create(Type="海洋",Name="海龟",Li_ID=2)
return HttpResponse("添加成功")
def Del_data(request): #删除数据函数
Animal_Table.objects.filter(Name="鲸鱼").delete() # 根据字段查找,并删除对应行
return HttpResponse("删除成功")
def Up_data(request): #更新数据函数
Animal_Table.objects.filter(Name="老虎").update(Type="猪圈") # 查询指定字段所在行,给该行要修改的字段从新赋值
return HttpResponse("更新成功")
def Sel_data(request): #查询数据函数
Obj_Mut = Animal_Table.objects.all() # 获取对象集合
print("对象集合:",Obj_Mut)
Obj_One = Obj_Mut[1] # 获取特定的对象
print("集合中的对象:",Obj_One)
Obj_Pro = Obj_One.Type # 获取特定的对象字段值【类型】
print("对象对应值-类型:",Obj_Pro)
Obj_Name = Obj_One.Name # 获取特定的对象字段值【名字】
print("对象对应值-姓名:",Obj_Name)
sel_num = Animal_Table.objects.count() # 获取查询出来的所有数量
print("查询数量为:",sel_num)
return HttpResponse(Obj_Pro,Obj_Name)
models.py
# -*- coding:utf8 -*-
from django.db import models
########################################## 创建表 #########################################
class Animal_Table(models.Model):
Type=models.CharField(max_length=20) #创建字符串字段,最大长度为20
Name=models.CharField(max_length=20) #创建字符串字段,最大长度为20
Li_ID=models.IntegerField() #创建整型字段
def __str__(self): #类str方法,用于调取显示字符串而不是内存地址
return self.Name
apps.py
from django.apps import AppConfig
class AppConfig(AppConfig):
name = 'APP'
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<a href="/add/">添加数据</a>
<a href="/delete/">删除数据</a>
<a href="/update/">更改数据</a>
<a href="/select/">查询数据</a>
</div>
</body>
</html>
数据库生成
执行完成后 项目 migrations 会生成数据库变更文件,本示例生成文件为0001_initial.py
python manage.py makemigrations APP
python manage.py migrate
运行测试
运行服务
python manage.py runserver 8000
测试需要访问 http://127.0.0.1:8000 测试