一. ORM 对象关系映射
类 ------ 表
类对象 ------ 记录
类属性 ------ 字段
二. 连接数据库配置
1.在 setting.py 文件中重新设置 DATABASES
① 删除原有的 sqlite3配置的 DATABASES
#sqlite3的配置 # DATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), # } # }
注: sqlite3 是django 自带的数据库 功能较mysql 差
② 添加连接 mysql 配置的 DATABASES
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'orm1', # 要连接的数据库,连接前需要创建好 'USER':'root', # 连接数据库的用户名 'PASSWORD':'222', # 连接数据库的密码 'HOST':'127.0.0.1', # 连接主机,默认本级 'PORT':3306 # 端口 默认3306 } }
2.在项目中 init.py 文件里面写上
import pymysql pymysql.install_as_MySQLdb()
3.添加 app 应用是 在setting 文件中 进行注册
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', #方式1 'app02', #方式2 ]
4.数据库每次修改要执行命令(在terminal 执行)
Python manage.py makemigrations (在 migrations 文件中进行记录)
Python manage.py migrate (创建表)
三.创建表的操作 (在django中不能创建库)
1.基本方式(在应用里的 models.py 文件中创建表 ,字段)
示例
class Book(models.Model): id = models.AutoField(primary_key=True) #主键 title = models.CharField(max_length=32,unique=True) #字符串 price = models.DecimalField(max_digits=16,decimal_places=2) #小数 pub_time = models.DateField() #日期 publish = models.CharField(max_length=20)
# def __str__(self):
# return self.title
2.更多字段
''' <1> CharField 字符串字段, 用于较短的字符串. CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数. <2> IntegerField #用于保存一个整数. <3> FloatField 一个浮点数. 必须 提供两个参数: 参数 描述 max_digits 总位数(不包括小数点和符号) decimal_places 小数位数 举例来说, 要保存最大值为 999 (小数点后保存2位),你要这样定义字段: models.FloatField(..., max_digits=5, decimal_places=2) 要保存最大值一百万(小数点后保存10位)的话,你要这样定义: models.FloatField(..., max_digits=17, decimal_places=10) #max_digits大于等于17就能存储百万以上的数了 admin 用一个文本框()表示该字段保存的数据. <4> AutoField 一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段; 自定义一个主键:my_id=models.AutoField(primary_key=True) 如果你不指定主键的话,系统会自动添加一个主键字段到你的 model. <5> BooleanField A true/false field. admin 用 checkbox 来表示此类字段. <6> TextField 一个容量很大的文本字段. admin 用一个 '''
3.更多参数
(1)null 是否可为空 ,如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False. (1)blank 如果为True,该字段允许不填。默认为False。 要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。 如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。 (2)default 字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用,如果你的字段没有设置可以为空,那么将来如果我们后添加一个字段,这个字段就要给一个default值 (3)primary_key 如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True, Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为, 否则没必要设置任何一个字段的primary_key=True。 (4)unique 如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的 (5)choices 由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,
默认的表单将是一个选择框而不是标准的文本框,
而且这个选择框的选项就是choices 中的选项。
四.记录的 增 ,删 ,改 ,查 .
1.增
方式1:
book_obj = models.Book(title=’xx’,pub=’xx’)
Book_obj.save()
book_obj=Book(title="python葵花宝典",state=True,price=100,publish="苹果出版社",
pub_date="2012-12-12") #实例化一个对象表示一行记录,时间日期如果只写日期的话,
时间默认是00.00.00,注意日期写法必须是2012-12-12这种格式 book_obj.save() #就是pymysql的那个commit提交
方式2:
models.Book.objects.create(title=’xx’,pub=’xx’)
# create方法的返回值book_obj就是插入book表中的python葵花宝典这本书籍纪录对象 book_obj=Book.objects.create(title="python葵花宝典",state=True,
price=100,publish="苹果出版社",pub_date="2012-12-12") #这个返回值就像是mysql
里面咱们讲的那个new对象,还记得吗,他跟上面那种创建方式创建的那个对象是一样的 #这个Book.objects就像是一个Book表的管理器一样,提供了增删改查所有的方法 print(book_obj.title) #可以基于这个对象来取这个新添加的记录对象的属性值 dic1 = {'title':'linux','state'=True,'price':100,'publish'='2018-12-12'}
#这样写的时候,注意如果你用post提交过来的请求,有个csrf_token的键值对要删除,
并且request.POST是不能直接在request.POST里面进行修改和删除的,data = request.POST.dict()
转换成普通的字典-->Book.objects.create(**data) book.objects.create(**dic1)
方式3: 批量增加(bulk_creat)
def test(request): # 1.这是一个一个添加,速度慢 # for i in range(100): # models.UserInfo.objects.create( # name='alex%s' % i, # password='sb%s' % i, # )
# 2.创建100个对象 加入列表 ,速度快(推荐) obj_list = [] for i in range(100): obj = models.UserInfo( name='wusir%s'%i, password='wusirsb%s'%i, ) obj_list.append(obj)
models.UserInfo.objects.bulk_create(obj_list) return HttpResponse('ok')
2.删
delete()方法的调用者可以是一个model对象,也可以是一个queryset集合。
models.Book.objects.filter(title=’水浒传’,id=2).delete()
3.改
models.Book.objects.filter(title=’水浒传’,id=2).update(title=’水浒传2’)
4.查
(都是querset 类型 ,类似于列表)
① 查询所有的
models.Book.objects.all()
②查询筛选的
models.Book.objects.filter(title=’水浒传’,id=2) and多添加查询
<1> all(): 查询所有结果,结果是queryset类型
<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象,结果也是queryset类型
Book.objects.filter(title='linux',price=100) #里面的多个条件用逗号分开,并且这几个条件必须都成立,是and的关系,
or关系的我们后面再学,直接在这里写是搞不定or的
<3> get(**kwargs): 返回与所给筛选条件相匹配的对象,不是queryset类型,是行记录对象,返回结果有且只有一个,
如果符合筛选条件的对象超过一个或者没有都会抛出错误。捕获异常try。 Book.objects.get(id=1)
<4> exclude(**kwargs): 排除的意思,它包含了与所给筛选条件不匹配的对象,没有不等于的操作昂,用这个exclude,
返回值是queryset类型 Book.objects.exclude(id=6),返回id不等于6的所有的对象,
或者在queryset基础上调用,Book.objects.all().exclude(id=6)
<5> order_by(*field): queryset类型的数据来调用,对查询结果排序,默认是按照id来升序排列的,
返回值还是queryset类型
models.Book.objects.all().order_by('price','id') #直接写price,默认是按照price升序排列,
按照字段降序排列,就写个负号就行了order_by('-price'),order_by('price','id')是多条件排序,
按照price进行升序,price相同的数据,按照id进行升序
<6> reverse(): queryset类型的数据来调用,对查询结果反向排序,返回值还是queryset类型
<7> count(): queryset类型的数据来调用,返回数据库中匹配查询(QuerySet)的对象数量。
<8> first(): queryset类型的数据来调用,返回第一条记录
Book.objects.all()[0] = Book.objects.all().first(),得到的都是model对象,不是queryset
<9> last(): queryset类型的数据来调用,返回最后一条记录
<10> exists(): queryset类型的数据来调用,是否包含数据 .如果QuerySet包含数据,就返回True,否则返回False
空的queryset类型数据也有布尔值True和False,但是一般不用它来判断数据库里面是不是有数据,
如果有大量的数据,你用它来判断,那么就需要查询出所有的数据,效率太差了,用count或者exits
例:all_books = models.Book.objects.all().exists()
#翻译成的sql是SELECT (1) AS `a` FROM `app01_book` LIMIT 1,
就是通过limit 1,取一条来看看是不是有数据
<11> values(*field): 用的比较多,queryset类型的数据来调用,
返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
model的实例化对象,而是一个可迭代的字典序列,只要是返回的queryset类型,
就可以继续链式调用queryset类型的其他的查找方法,其他方法也是一样的。
<12> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
<13> distinct(): values和values_list得到的queryset类型的数据来调用,从返回结果中剔除重复纪录
13条的输出结果: 对象列表 all filter exclude() values() values_list() order_by() reverse() distinct() 对象 get first last 布尔值 exists 数字 count
③模糊查询
Book.objects.filter(price__in=[100,200,300]) #price值等于这三个里面的任意一个的对象 Book.objects.filter(price__gt=100) #大于,大于等于是price__gte=100,别写price>100,这种参数不支持 Book.objects.filter(price__lt=100) #小于 Book.objects.filter(price__range=[100,200]) #sql的between and,大于等于100,小于等于200 Book.objects.filter(title__contains="python") #title值中包含python的 Book.objects.filter(title__icontains="python") #不区分大小写 Book.objects.filter(title__startswith="py") #以什么开头,istartswith 不区分大小写 Book.objects.filter(pub_date__year=2012)
日期查询示例
# all_books = models.Book.objects.filter(pub_date__year=2012) #找2012年的所有书籍 # all_books = models.Book.objects.filter(pub_date__year__gt=2012)#找大于2012年的所有书籍 all_books = models.Book.objects.filter(pub_date__year=2019,pub_date__month=2)#找2019年月份的所有书籍,
如果明明有结果,你却查不出结果,是因为mysql数据库的时区和咱们django的时区不同导致的,了解一下就行了,
你需要做的就是将django中的settings配置文件里面的USE_TZ = True改为False,就可以查到结果了,以后这个值就改为False,
而且就是因为咱们用的mysql数据库才会有这个问题,其他数据库没有这个问题。
五.pucharm 自带的数据库管理
①
②
③
④