Django-03数据库操作

数据库

1.定义模型类

在models.py中定义模型类,继承自models.Model

from django.db import models

# Create your models here.

class 模型类A(models.Model):
    # 创建字段,字段类型...
    name = models.CharField(max_length=10)

class 模型类B(models.Model):
    gender = models.BooleanField()
    # 外键约束(B中某物属于A中某类)
    book = models.ForeignKey(模型类A,on_delete=models.CASCADE)

模型类优化

class 模型类A(models.Model):
    name = models.CharField(max_length=10)
  # ------------------------------------------
    def __str__(self):
        """将模型类以字符串的方式输出"""
        return self.name

1)主键

django会为表创建自动增长的主键列,每个模型只能有一个主键列,如果选项设置某属性为主键列后,django将不会再创建自动增长的主键列。

默认创建的主键列属性为id,可以使用pk代替(全屏为primary key)

2)属性命名限制

不能是python的保留关键字

不允许使用连续下划线(django查询方式决定)

定义属性时需要指定字段类型,语法:属性=models.字段类型(选项)

字段类型

类型 说明
AutoField 自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性
BooleanField 布尔字段,值为True或False
NullBooleanField 支持Null、True、False三种值
CharField 字符串,参数max_length表示最大字符个数
TextField 大文本字段,一般超过4000个字符时使用
IntegerField 整数
DecimalField 十进制浮点数, 参数max_digits表示总位数, 参数decimal_places表示小数位数
FloatField 浮点数
DateField 日期, 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为False; 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
TimeField 时间,参数同DateField
DateTimeField 日期时间,参数同DateField
FileField 上传文件字段
ImageField 继承于FileField,对上传的内容进行校验,确保是有效的图片

选项

选项 说明
null 如果为True,表示允许为空,默认值是False
blank 如果为True,则该字段允许为空白,默认值是False
db_column 字段的名称,如果未指定,则使用属性的名称
db_index 若值为True, 则在表中会为此字段创建索引,默认值是False
default 默认
primary_key 若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
unique 如果为True, 这个字段在表中必须有唯一值,默认值是False

外键

在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:

  • CASCADE级联,删除主表数据时连通一起删除外键表中数据
  • PROTECT保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据
  • SET_NULL设置为NULL,仅在该字段null=True允许为null时可用
  • SET_DEFAULT设置为默认值,仅在该字段设置了默认值时可用
  • SET()设置为特定值或者调用特定方法
  • DO_NOTHING不做任何操作,如果数据库前置指明级联性,此选项会抛出IntegrityError异常

2.配置数据库

setting.py中默认使用sqlite数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

使用mysql数据库

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',  # 数据库主机
        'PORT': 3306,  # 数据库端口
        'USER': 'root',  # 数据库用户名
        'PASSWORD': 'mysql',  # 数据库用户密码
        'NAME': 'book'  # 数据库名字
    }
}

3.模型迁移

生成迁移文件:根据模型类生成创建表的语句

python manage.py makemigrations

执行迁移:根据第一步生成的语句在数据库中创建表

python manage.py migrate

4.运行测试

需要安装MySQL数据库的客户端驱动

pip install mysqlclient==1.4.6 -i https://pypi.tuna.tsinghua.edu.cn/simple/

若还是报错,则需要安装libmysqlclient-dev(虚拟机中)

sudo apt-get install libmysqlclient-dev

5.数据库操作

1)save

>>> from 子应用名.models import 类名
>>> 对象a = 模型类A(
...         name='python入门',
...         pub_date='2010-1-1'
...     )
>>> 对象a.属性1 = 属性值
>>> 对象a.属性2 = 属性值
>>> 对象a.save()

2)create

>>> 模型类A.objects.create(
...         name='itheima',
...         book=book
...     )

1)save

修改模型类对象的属性,然后执行save()

>>> 对象a = 模型类A.objects.get(属性='原信息')
>>> 对象a.属性 = '新信息'
>>> 对象a.save()

2)update

>>> 模型类A.objects.filter(属性='原信息').update(属性='新信息')

1)模型类对象delete

>>> 对象a = 模型类A.objects.get(属性='信息')
>>> 对象a.delete()

2)模型类.objects.filter().delete()

>>> 模型类A.objects.filter(属性='信息').delete()

基本查询

1)get 查询单一结果,如果不存在会抛出模型类.DoesNotExist异常

>>> 模型类A.objects.get(属性=信息)

2)all 查询多个结果

>>> 模型类A.objects.all()

3)count 查询数量

>>> 模型类A.objects.count()

4)filter 查询所有

>>> 模型类A.objects.filter()

5)exclude() 不等于 取反

>>> 模型类A.objects.exclude()

过滤查询

属性名称__比较运算符=值
# 属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线
BookInfo.objects.filter(id__exact=1)
可简写为:
BookInfo.objects.filter(id=1)

               比较运算符                  	      功能       	      举例      
               exact                  	      相等       	  可简写为:id=1   
              contains                	     是否包含      	__contains='传'
        startswith、endswith           	    指定开头或结尾    	__endswith='部'
               isnull                 	     是否为空      	__isnull=True 
                 in                   	    是否在范围内     	 __in=[1,3,5] 
           gt,gte,lt,lte              	大于,大于等于,小于,小于等于	    __gt=3    

year,month,day,week_day,hour,minute,second 日期时间类型 __year=1980

例:查询1990年1月1日后发表的图书。

>>> BookInfo.objects.filter(pub_date__gt='1990-1-1')

F 实现属性之间的比较

from django.db.models import F,Q
# 阅读量大于等于2倍评论量
BookInfo.objects.filter(breade__gte = F('bcomment'))

Q 实现mysql里的not and or

符号 功能
& and
| or
~ not

聚合函数.aggregate()

返回一个字典

Avg 平均
Count 数量 一般不使用,直接用count()
Max 最大 aggregate(Max(‘属性’))
Min 最小
Sum 求和

排序 .order_by()

升序: .order_by(‘属性’)

降序: .order_by(’-属性rd’)

关联查询

获取1对应的多的一方的数据

# 1的对象.多的模型类小写_set.all()
bookinfo.heroinfo_set.all()

获取多对应的1的一方的数据

# 直接使用外键
heroinfo.bookinfo
heroinfo.bookinfo_id

关联过滤查询

查询英雄是郭靖的书籍

bookinfo.object.filter(heroinfo__name='郭靖')

查询图书 书的描述包含’掌’

bookinfo.objects.filter(heroinfo__desc__contains='掌')

查询多的模型 条件是对1的一方属性进行判断

条件使用关联的模型类的字典 1模型类外键名__1模型类属性名__条件运算符=值

查询天龙八部的所有英雄

heroinfo.objects.filter(book_title='天龙八部')

查看MySQL日志的位置

cat mysql.log

查询集QuerySet

1.惰性执行

创建查询集不会访问数据库,直到调用时才会访问数据库,调用情况包括迭代、序列化、与if合用。

books = bookinfo.objects.all() # 这时查看MySQL日志发现没有执行

for b in books:
	print(b.title) # 执行了语句

2.缓存

使用一个查询集,第一次使用时会发生数据库的查询,然后django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数。

情况1:每次查询都与数据库进行交互,增加了数据库的负载

for i in hero.object.all():
    print(i.name)
for i in hero.object.all():
    print(i.name)

情况2:经过存贮后,可以重用查询集,第二次使用缓存中的数据

heros = heroinfo.object.all()
for i in heros:
    print(i.name)
for i in heros:
    print(i.name)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值