django

Posted zdq1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django相关的知识,希望对你有一定的参考价值。

一、常见字段

1.1AutoField int primary key auto_increment

int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。

1.2IntegerField

? 一个整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,),手机号用charfield来存,但django中没有chafield字段,即便写的charField字段,你写charfield,在数据库里看还是varcahr!!

? charfield和varcharfield最大255.存文本用textfield

技术图片

自定义char字段(写在是参照源码来的)
class MyChar(models.Field):
    def __init__(self,max_length,*args,**kwargs):
        self.max_length = max_length
        super().__init__(max_length=max_length,*args,**kwargs)

    def db_type(self, connection):
        return 'char(%s)'%self.max_length

? max_length必须以关键字的方式,因为源码就是这么定义的。

技术图片

? 现在,就可以定义char字段了

desc = MyChar(max_length=64,null=True)
1.3DateField

日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。

1.4DateTimeField

日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。

参数:

? auto_now:每次修改数据都会更新时间

? auto_now_add:只在第一次创建数据的时候才会更新一次

1.5BooleanField(Field)

? is_delete = BooleanField()

? 给该字段传值的时候 你只需要传布尔值(传True和False)即可

? 但是对应到数据库 它存的是0和1

1.6TextField(Field)

? 用来存大段文本

? 数据库通常不能存文件的,因为太大,因此存文件路径

1.7FileField(Field)

  • 字符串,路径保存在数据库,文件上传到指定目录
  • 参数:
    upload_to = "" 用户上传的文件会自动放到等号后面指定的文件路径中
    storage = None 存储组件,默认django.core.files.storage.FileSystemStorage

4.索引

技术图片

**补充外键字段:**

?```python
当你在使用django2.X版本的时候 在建立外键关系时(*****)
需要你手动添加几个关键点参数
models.cascade
db_constraints

二、数据库查询优化:only与defer

orm内所有的语句操作 都是惰性查询:只会在你真正需要数据的时候才会走数据库,如果你单单只写orm语句时不会走数据库的。这样设计的好处 在于 减轻数据库的压力

2.1.only()

? values()得到的是一个个QuerySet字典!!!

? 使用.all()的方式才能得到QuerySet对象

res = models.Book.objects.values('title')
print(res)
笔记:values传title,得出的字典K值都是title!
#<QuerySet ['title': '西游记', 'title': '水浒传', 'title': '龙王脑海 ']>

? only得到的是对象!而value得到的是字典!通过点,进行取值,不再访问数据库

models.Book.objects.only('title')
for r in res:
    print(r.title)  # 只走一次数据库查询
    print(r.price)  # 当你点击一个不是only括号内指定的字段的时候 不会报错 而是会频繁的走数据库查询
#笔记 only得出的结果是QuerySet对象,k为Book,v为only括号内的值
<QuerySet [<Book: 西游记>, <Book: 水浒传>, <Book: 龙王脑海 >]>

技术图片

2.2defer

only和defer查询出来的结果都是QuerySet对象

res1 = models.Book.objects.defer('title')  # defer与only是相反的
for r in res1:  # defer会将不是括号内的所有的字段信息 全部查询出来封装对象中
    # 一旦你点击了括号内的字段  那么会频繁的走数据库查询
    print(r.title)


#结果
(0.001) SELECT `app01_book`.`id`, `app01_book`.`price`, `app01_book`.`publish_date`, `app01_book`.`kucun`, `app01_book`.`maichu`, `app01_book`.`publish_id` FROM `app01_book`; args=()
(0.001) SELECT `app01_book`.`id`, `app01_book`.`title` FROM `app01_book` WHERE `app01_book`.`id` = 1; args=(1,)
(0.000) SELECT `app01_book`.`id`, `app01_book`.`title` FROM `app01_book` WHERE `app01_book`.`id` = 2; args=(2,)
西游记
水浒传
(0.000) SELECT `app01_book`.`id`, `app01_book`.`title` FROM `app01_book` WHERE `app01_book`.`id` = 4; args=(4,)
龙王脑海 

3.2.all()和select_related()的区别

1.all()查询次数非常多

? all()查询效率非常低,循环依次系统查询一次,查询次数非常多

res = models.Book.objects.all()
for r in res:
    print(r.publish.name) # 补充:r.publish.name这是跨表

技术图片

会将外键字段关联的表全部拼接过来,对象点属性,不走数据库。select_related:会将括号内外键字段所关联的那张表 直接全部拿过来(可以一次性拿多张表)跟当前表拼接操作,从而降低你跨表查询 数据库的压力

注意select_related括号只能放外键字段(一对一和一对多)
res = models.Book.objects.all().select_related(‘外键字段1__外键字段2__外键字段3__外键字段4‘)。那现在他一下将5张表连在一起,还是一句sql语句!

若果有一千万条数据,.all()的方法,要走1000万次数据库,对数据库压力非常大

res = models.Book.objects.all().select_related('publish')
print(res)# <QuerySet [<Book: 龙王脑海 >, <Book: 西游记>, <Book: 水浒传>]>
for r in res:
    print(r.publish.name)
#查询语句:一整条,只走一次数据库
(0.001) SELECT `app01_book`.`id`, `app01_book`.`title`, `app01_book`.`price`, `app01_book`.`publish_date`, `app01_book`.`kucun`, `app01_book`.`maichu`, `app01_book`.`publish_id`, `app01_publish`.`id`, `app01_publish`.`name`, `app01_publish`.`addr` FROM `app01_book` INNER JOIN `app01_publish` ON (`app01_book`.`publish_id` = `app01_publish`.`id`) LIMIT 21; args=()

3.prefetch_related 不主动连表

res = models.Book.objects.prefetch_related('publish')
不主动连表操作(但是内部给你的感觉像是连表操作了)  而是将book表中的publish id全部拿出来  在取publish表中将id对应的所有的数据取出
res = models.Book.objects.prefetch_related('publish')
括号内有几个外键字段 就会走几次数据库查询操作    
for r in res:
    print(r.publish.name)

4.prefetch_related 与select_related的区别:

select_related,先连表再查,事件消耗在连表上,只走一次数据库。

prefetch_related ,括号内有几个外键字段 就会走几次数据库查询操作

3.3事务

原子性:要么同时成功,要么同时失败(转账例子)

一致性:

隔离性:互相不影响

持久性:产生的影响是永远的

orm中的事务,很简单

开启事务:在事务内的代码会保持事务的4个特性

from django.db import transaction
with transaction.atomic():
    """数据库操作
       在该代码块中书写的操作 同属于一个事务
    """
print('出了 代码块 事务就结束')

图书管理系统

? · mysql比django自带数据库对日期铭感一点

1.更换并连接mysql数据库:

? 1.settings:databases:

? 2.init内的两句代码

2.录入数据

3.url加主页:from app01 import views

4.views写函数

5.html文件:

? staticdirs = 【os.path.join,‘static’】

? static中引入bootstrcip

? % load static

以上是关于django的主要内容,如果未能解决你的问题,请参考以下文章

DjangoDjango 文件下载最佳实践

DjangoDjango模块创建应用程序

DjangoDjango 如何支持 分组查询统计?

DjangoDjango Debug Toolbar调试工具配置

DjangoDjango中的模糊查询以及Q对象的简单使用

djangodjango-redis的使用方法