数据库配置:

#第一步在settings里面

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'dbname',
'USER': 'root',
'PASSWORD': 'xxx',
'HOST': 'xx',
'PORT': 6666,
}
} #第二步
# 如下设置放置的与project同名的配置的 __init__.py文件中
import pymysql
pymysql.install_as_MySQLdb() 

数据库基本操作

conn = pymysql.connect(host='localhost', port=3307, user='root', passwd='88888', db='learing',charset='utf8')
# 创建连接 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
# 创建游标 cursor.execute("select id,title from class")
#执行SQL语句
#cursor.fetchone() #是个字典
#conn.commit() 增、删、改
class_list=cursor.fetchall()
cursor.close()
conn.close() #--------大量重复后可以将其功能写成一个类 class SqlHelper(): # def __init__(self):
# self.connect()
#也可以把那个链接的内容写成配置文件(活的)
#只要一建立对象,就直接链接上 def connect(self):
self.conn=pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='94188', db='exercise',charset='utf8')
self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) def get_list(self,sql,args):
self.cursor.execute(sql,args)
result=self.cursor.fetchall()
return(result) def get_one(self,sql,args):
self.cursor.execute(sql,args)
result = self.cursor.fetchone()
return (result) def modify(self,sql,args):
self.cursor.execute(sql,args)
self.conn.commit() def multiple_modify(self,sql,args):
#self.cursor.executemany('insert into ba(id,name)'value(%s,%s),[(1,'abv'),(2,'ffff')])
self.cursor.executemany(sql,args)
self.conn.commit() def add_create(self,sql,args):
self.cursor.execute(sql,args)
self.conn.commit()
return self.cursor.lastrowid #获取最后的一个id并且返回 def close(self):
self.cursor.close()
# 关闭连接
self.conn.close() #后面使用建立个类的对象,调用其方法就行
obj = SqlHelper()
obj.connect()
obj.get_list()
...
obj.close()

ORM操作

ORM利用pymysql等第三方工具连接数据库

Django默认连接SQLlite(文件型数据库db.sqlite3)

所以要把setting里面修改为

DATABASES = {

    'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'Kant',
} }
#这个数据库要事先创建好

默认用的是mysql-->MySQLDB(下面方法修改Django默认连接方式)

# 如下设置放置的与project同名的配置的 __init__.py文件中

import pymysql
pymysql.install_as_MySQLdb() 

在目录app01--models.py里面 写上对应的类,然后生成表

class UserGroup(models.Model):
title=models.CharField(max_length=32)
#生成的表会自动带id属性, #然后顺序执行下面个代码(每次修改表都要顺序执行一遍)
#python manage.py makemigrations
#python manage.py migrate

基本操作语句

models.UserInfo.objects.create(user='程颢',password=12306,age=365,ug_id=1)
#增加 models.UserGroup.objects.filter(id=2).delete()
#删除 models.UserGroup.objects.filter(id=1).update(title='明道先生')
#修改 models.UserGroup.objects.filter(id=2).first()
resdult=models.UserInfo.objects.all()
models.Tb1.objects.get(id=123) #获取单条数据,不存在则报错,不推荐
#查找

补充语句(.values()  &  .all()  & .filter(**condition) )

resdult=models.UserInfo.objects.all().values('user','age')  # 字典类型python
for row in resdult:
print(row,row['user']) #从完整表找出其'user','age',以之为key构造关于其对应内容的字典
#格式为:{'user': '程颐', 'age': 18, } resdult=models.UserInfo.objects.all()
#<QuerySet [<UserInfo: 1-程颐>, <UserInfo: 2-王阳明>]>
#拿到表全部数据,形式类似列表,可通过循环或者.values获取相关分量 resdult=models.UserInfo.objects.all().first
#取出第一个对象,相当于一行(一个元组)
#可以通过(.属性名)来获取相关分量

condition={'xx':'xx','yy':'yy'}

models.UserGroup.objects.filter(**condition)
#还可以传字典,查询的时候是and的关系

进阶操作(神奇双下划线__进行数据库操作)

# 获取个数
#
# models.Tb1.objects.filter(name='seven').count() # 大于,小于
#
# models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值
# models.Tb1.objects.filter(id__gte=1) # 获取id大于等于1的值
# models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lte=10) # 获取id小于10的值
# models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值 # in
#
# models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
# models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in # isnull
# Entry.objects.filter(pub_date__isnull=True) # contains
#
# models.Tb1.objects.filter(name__contains="ven")
# models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
# models.Tb1.objects.exclude(name__icontains="ven") # range
#
# models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and # 其他类似
#
# startswith,istartswith, endswith, iendswith, # order by
#
# models.Tb1.objects.filter(name='seven').order_by('id') # asc
# models.Tb1.objects.filter(name='seven').order_by('-id') # desc # group by
#
# from django.db.models import Count, Min, Max, Sum
# models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id" # limit 、offset
#
# models.Tb1.objects.all()[10:20] # regex正则匹配,iregex 不区分大小写
#
# Entry.objects.get(title__regex=r'^(An?|The) +')
# Entry.objects.get(title__iregex=r'^(an?|the) +') # date
#
# Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
# Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1)) # year
#
# Entry.objects.filter(pub_date__year=2005)
# Entry.objects.filter(pub_date__year__gte=2005) # month
#
# Entry.objects.filter(pub_date__month=12)
# Entry.objects.filter(pub_date__month__gte=6) # day
#
# Entry.objects.filter(pub_date__day=3)
# Entry.objects.filter(pub_date__day__gte=3) # week_day
#
# Entry.objects.filter(pub_date__week_day=2)
# Entry.objects.filter(pub_date__week_day__gte=2) # hour
#
# Event.objects.filter(timestamp__hour=23)
# Event.objects.filter(time__hour=5)
# Event.objects.filter(timestamp__hour__gte=12) # minute
#
# Event.objects.filter(timestamp__minute=29)
# Event.objects.filter(time__minute=46)
# Event.objects.filter(timestamp__minute__gte=29) # second
#
# Event.objects.filter(timestamp__second=31)
# Event.objects.filter(time__second=2)
# Event.objects.filter(timestamp__second__gte=31) 进阶操作

 F、Q、extra

###F可把表里面同一属性集体增减,比如全部人工资增加1000
from django.db.models import F
models.Tb1.objects.update(salary=F('salary')+1000) ###Q可以多复杂条件同时查询(同时存在and & or)
from django.db.models import Q #Q是写在.filter()里面 方法一: Q(id=10)
Q(id=8) | Q(id=10) #or
Q(id=8) & Q(id=10) #and
Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
models.UserInfo.objects.filter(Q(nid=1) | Q(nid=3) ).all().values('user','age',).first()['user'] 方法二: # q1 = Q()
# q1.connector = 'OR'
# q1.children.append(('id', 1))
# q1.children.append(('id', 10))
# q1.children.append(('id', 9))
#q1内部加这么多条件通过OR连接 # q2 = Q()
# q2.connector = 'OR'
# q2.children.append(('c1', 1))
# q2.children.append(('c1', 10))
# q2.children.append(('c1', 9))
#q2内部加这么多条件通过OR连接 con = Q()
con.add(q1, 'AND')
con.add(q2, 'AND')
#con内部加这么多条件通过AND连接
#以便应对组合查询 #可以写个字典,动态生成这个查询 #models.Tb1.objects.filter(con) ###extra,额外的
# extra(self, select=None,select_params=None, where=None, params=None, tables=None, order_by=None, )
# Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
# Entry.objects.extra(where=['headline=%s'], params=['Lennon']) #where跟 params匹配用
# Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"]) #列表元素跟元素之间通过and连接,元素内部可以用or连接
# Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
# Entry.objects.extra(tables=['app01_usertype'],where=[])
#相当于select * from Entry,app01_usertype #笛卡尔积 v=models.UserInfo.objects.all().extra(select={'n':'select count(1) from app01_UserGroup where id>%s and id<%s' },select_params=[1,4])
for i in v:
print(i.user,i.n)
#占位符号多的话可以挨个加, 往后面加就行
#这个i.n为新的字段(列)会加到查询的表中 extra
#可以全部用上
models.UserInfo.objects.extra ( select={ 'newid' : 'select count(1) from app01_ usertype where id>&s'},
select_ params=[1,] , where =['age>%s'] ,
params= [18,], order_by=['-age'],
tables= ['app01_ usertype'] )
相当于:
select
app01_userinfo.id,
(select count(1) from app01_usertype where id>1) as newid
from app01_userinfo, app01_ usertype
where
app01_ userinfo.age > 18
order by
app01_ userinfo.age desc # 执行原生SQL
# from django.db import connection, connections
# cursor = connection.cursor() #默认的数据库
# cursor = connections['default'].cursor() #指定的数据库 settings里面可以DATABASES可以有多个数据库
# cursor.execute("""SELECT * from auth_user where id = %s""", [1])
# row = cursor.fetchone()
# row = cursor.fetchall()

models. xxx.objects.**   .  **可以是一些操作(多)

##################################################################
# PUBLIC METHODS THAT ALTER ATTRIBUTES AND RETURN A NEW QUERYSET #
################################################################## def all(self)
# 获取所有的数据对象 def filter(self, *args, **kwargs)
# 条件查询
# 条件可以是:参数,字典,Q def exclude(self, *args, **kwargs)
# 条件查询
# 条件可以是:参数,字典,Q def select_related(self, *fields)
性能相关:表之间进行join连表操作,一次性获取关联的数据。
model.tb.objects.all().select_related()
model.tb.objects.all().select_related('外键字段')
model.tb.objects.all().select_related('外键字段__外键字段') def prefetch_related(self, *lookups)
性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。
# 获取所有用户表
# 获取用户类型表where id in (用户表中的查到的所有用户ID)
models.UserInfo.objects.prefetch_related('外键字段') from django.db.models import Count, Case, When, IntegerField
Article.objects.annotate(
numviews=Count(Case(
When(readership__what_time__lt=treshold, then=1),
output_field=CharField(),
))
) students = Student.objects.all().annotate(num_excused_absences=models.Sum(
models.Case(
models.When(absence__type='Excused', then=1),
default=0,
output_field=models.IntegerField()
))) def annotate(self, *args, **kwargs)
# 用于实现聚合group by查询 from django.db.models import Count, Avg, Max, Min, Sum v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id'))
# SELECT u_id, COUNT(ui) AS `uid` FROM UserInfo GROUP BY u_id v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id')).filter(uid__gt=1)
# SELECT u_id, COUNT(ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1 v = models.UserInfo.objects.values('u_id').annotate(uid=Count('u_id',distinct=True)).filter(uid__gt=1)
# SELECT u_id, COUNT( DISTINCT ui_id) AS `uid` FROM UserInfo GROUP BY u_id having count(u_id) > 1 def distinct(self, *field_names)
# 用于distinct去重
models.UserInfo.objects.values('nid').distinct()
# select distinct nid from userinfo 注:只有在PostgreSQL中才能使用distinct进行去重 def order_by(self, *field_names)
# 用于排序
models.UserInfo.objects.all().order_by('-id','age') def extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
# 构造额外的查询条件或者映射,如:子查询 Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid']) def reverse(self):
# 倒序
models.UserInfo.objects.all().order_by('-nid').reverse()
# 注:如果存在order_by,reverse则是倒序,如果多个排序则一一倒序 def defer(self, *fields):
models.UserInfo.objects.defer('username','id')

models.UserInfo.objects.filter(...).defer('username','id')
#映射中排除某列数据 def only(self, *fields):
#仅取某个表中的数据
models.UserInfo.objects.only('username','id')

models.UserInfo.objects.filter(...).only('username','id') def using(self, alias):
指定使用的数据库,参数为别名(setting中的设置) ##################################################
# PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS #
################################################## def raw(self, raw_query, params=None, translations=None, using=None):
# 执行原生SQL
models.UserInfo.objects.raw('select * from userinfo') # 如果SQL是其他表时,必须将名字设置为当前UserInfo对象的主键列名
models.UserInfo.objects.raw('select id as nid from 其他表') # 为原生SQL设置参数
models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,]) # 将获取的到列名转换为指定列名
name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
Person.objects.raw('SELECT * FROM some_other_table', translations=name_map) # 指定数据库
models.UserInfo.objects.raw('select * from userinfo', using="default") ################### 原生SQL ###################
from django.db import connection, connections
cursor = connection.cursor() # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1])
row = cursor.fetchone() # fetchall()/fetchmany(..) def values(self, *fields):
# 获取每行数据为字典格式 def values_list(self, *fields, **kwargs):
# 获取每行数据为元祖 def dates(self, field_name, kind, order='ASC'):
# 根据时间进行某一部分进行去重查找并截取指定内容
# kind只能是:"year"(年), "month"(年-月), "day"(年-月-日)
# order只能是:"ASC" "DESC"
# 并获取转换后的时间
- year : 年-01-01
- month: 年-月-01
- day : 年-月-日 models.DatePlus.objects.dates('ctime','day','DESC') def datetimes(self, field_name, kind, order='ASC', tzinfo=None):
# 根据时间进行某一部分进行去重查找并截取指定内容,将时间转换为指定时区时间
# kind只能是 "year", "month", "day", "hour", "minute", "second"
# order只能是:"ASC" "DESC"
# tzinfo时区对象
models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.UTC)
models.DDD.objects.datetimes('ctime','hour',tzinfo=pytz.timezone('Asia/Shanghai')) """
pip3 install pytz
import pytz
pytz.all_timezones
pytz.timezone(‘Asia/Shanghai’)
""" def none(self):
# 空QuerySet对象 ####################################
# METHODS THAT DO DATABASE QUERIES #
#################################### def aggregate(self, *args, **kwargs):
# 聚合函数,获取字典类型聚合结果
from django.db.models import Count, Avg, Max, Min, Sum
result = models.UserInfo.objects.aggregate(k=Count('u_id', distinct=True), n=Count('nid'))
===> {'k': 3, 'n': 4} def count(self):
# 获取个数 def get(self, *args, **kwargs):
# 获取单个对象 def create(self, **kwargs):
# 创建对象 def bulk_create(self, objs, batch_size=None):
# 批量插入
# batch_size表示一次插入的个数
objs = [
models.DDD(name='r11'),
models.DDD(name='r22')
]
models.DDD.objects.bulk_create(objs, 10) def get_or_create(self, defaults=None, **kwargs):
# 如果存在,则获取,否则,创建
# defaults 指定创建时,其他字段的值
obj, created = models.UserInfo.objects.get_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 2}) def update_or_create(self, defaults=None, **kwargs):
# 如果存在,则更新,否则,创建
# defaults 指定创建时或更新时的其他字段
obj, created = models.UserInfo.objects.update_or_create(username='root1', defaults={'email': '1111111','u_id': 2, 't_id': 1}) def first(self):
# 获取第一个 def last(self):
# 获取最后一个 def in_bulk(self, id_list=None):
# 根据主键ID进行查找
id_list = [11,21,31]
models.DDD.objects.in_bulk(id_list) def delete(self):
# 删除 def update(self, **kwargs):
# 更新 def exists(self):
# 是否有结果 其他操作

连表操作(了不起的双下划线、反查)

点击此处跳转

 性能优化

resdult=models.UserInfo.objects.all()
for row in resdult:
print(row.name,row.ut.title) #row.ut.title是通过外键ut跨表后查询另外表中对应的titile属性
#存在问题:这样要执行很多次数据库操作,比较耗资源

#改进1.查询一次,生成个字典,然后通过索引取值
resdult=models.UserInfo.objects.all().values('user','age','password') #.values字典类型 每一个元素都是一个字典(包含一行数据)
for row in resdult:
print(row,row['user']) #通过索引取值 #改进2.select_related主动做连表查询一次 (数据量小的时候可以用) resdult=models.UserInfo.objects.all().select_related('ut','gp',...) #直接与外键('ut','gp')连接的表(可以多个)连接起来 [一次就好]
for row in resdult: #row是对象
print(row.name,row.ut.title) # 这样就不同发额外sql请求 #与下面的prefetch_related比较:
#优点:节省硬盘空间
#缺点:连表性能差(用户量大的时候) #改进3:prefetch_related不做连表,做两次查询
#一次查询UserInfo整合结果集(去重),再根据已知条件查一次ut外键相关的那个表,然后两者结果合一。(数据量大的时候用) resdult=models.UserInfo.objects.all().prefetch_related('ut')
for row in resdult: #row是对象
print(row.name,row.ut.title) # 这样就不同发额外sql请求

 

最新文章

  1. 前端读取Excel报表文件
  2. 探索RegisterAllAreas
  3. XVI Open Cup named after E.V. Pankratiev. GP of SPB
  4. 终端可以连接MySQL但是navicat还是报错:Can&#39;t connect to MySQL server on &#39;127.0.0.1&#39;(61)
  5. DOM系列---DOM操作表格
  6. sdut 2165:Crack Mathmen(第二届山东省省赛原题,数论)
  7. 下拉列表autocomplete各种实现方式比较
  8. linux下文件编码的查看与修改
  9. hdu 2019
  10. JAVA在线基础教程!
  11. 配置分割Tomcat日志
  12. 程序猿必知必会Linux命令之awk
  13. Java程序设计第一次作业
  14. jdk7_ConcurrentHashMap 图示
  15. str中文初始化乱码,要用宽字符;if else
  16. webpack 中,importloaders 配置项的含义
  17. 两个有序数组长度分别为m,n,最多m+n次查找找出相同的数
  18. 【代码审计】XYHCMS V3.5文件上传漏洞分析
  19. Java课程作业之动手动脑(四)
  20. [Unity Shader] 切线空间的法线贴图

热门文章

  1. Java中CAS 基本实现原理 和 AQS 原理
  2. XMLBeanFactory ?
  3. @Qualifier 注解?
  4. idea常见设置一
  5. 集合流之“将List&lt;Integer&gt;转为String并用逗号分割”
  6. 机器学习优化算法之EM算法
  7. 无单位数字和行高 —— 别说你懂CSS相对单位
  8. React+dva+webpack+antd-mobile 实战分享(二)
  9. TextView显示html样式的文字
  10. MySQL中 tinyint、bigint、bit、text、decimal、year、date、time、datetime、timestamp等对应Java中什么类型