Django框架进阶5 models常用字段及参数, choices参数, 自动显示sql命令配置, orm查询优化相关, orm中的事务操作, MTV与MVC模型, 图书管理系统(图书的增删改查)

models中的常用字段

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

CharField(max_length=32)     varchar(32)

IntegerField()       int

BigIntergerField()           bigint

DecimalField()     decimal

EmailField()       varchar(254)

DateField()     date

DateTimeField()  datetime

  auto_now:每次编辑数据的时候都会自动更新该字段时间

  auto_now_add:创建数据的时候自动更新

BooleanField(Field)

  给该字段传布尔值  会对影成   数字0/1

  is_delete

  is_status

  is_vip

TextField(Field)

  -文本类型  存储大段文本

FileField(Field)

  - 字符串,路径保存在数据库,文件上传到指定目录,只存文件路径

    upload_to = '指定文件路径'

    给该字段传文件对象 文件会自动保存到upload_to指定的文件夹下 然后该字段存文件的路径

如何自定义char类型字段

from django.db.models import Field

class RealCharField(Field):
    def __init__(self,max_length,*args,**kwargs):
        self.max_length = max_length  # 拦截一个父类的方法 操作完之后 利用super调用父类的方法
        super().__init__(max_length=max_length,*args,**kwargs)

    def db_type(self, connection):
        return 'char(%s)'%self.max_length
        
class Movie(models.Model):
    textField = RealCharField(max_length=64)

字段内的关键性参数

  null  null=True  允许字段为空,必须用null

  default  默认参数

  django  1.x默认就是级联更新级联删除  django2.x需要你自己手动指定

    on_delete = models.CASCADE

    db_contraints = True

    # 百度

choice参数

  用户的性别
  学历
  婚否
  在职状态
  客户来源
  当你的数据能够被你列举完全 你就可以考虑使用choices参数

models.py

class Userinfo(models.Model):
    username = models.CharField(max_length=32)
    gender_choices = (
        (1,''),
        (2,''),
        (3,'其他'),
    )
    gender = models.IntegerField(choices=gender_choices)
    # 该字段还是存数字 并且可以匹配关系之外的数字
    record_choices = (('checked','已签到'),
                      ('vacate','请假'),
                      ('noshow','缺勤'),
                      ('leave_early','早退'),
                      )
    record = models.CharField('上课记录',choices=record_choices,default='checked',max_length=64)

test.py

user_obj = models.Userinfo.objects.get(pk=1)
print(user_obj.username)
print(user_obj.gender)
# 针对choices参数字段 取值的时候   get_xxx_display()
print(user_obj.get_gender_display())
# 针对没有注释信息的数据  get_xxx_display()获取到的还是数字本身
user_obj = models.Userinfo.objects.get(pk=4)
print(user_obj.gender)        # 100
print(user_obj.get_gender_display())    # 100

django自动显示sql命令配置

settings.py文件中加入

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

数据库查询优化(面试会问)

only与defer

only作用
括号内传字段 得到的结果是一个列表套数据对象 该对象内只含有括号内指定的字段属性
对象点该字段属性是不会走数据库的 但是你一旦点了非括号内的字段 也能够拿到数据
但是是重新走的数据库查询吧
defer与only相反
括号内传字段 得到的结果是一个列表套数据对象 该对象内没有括号内指定的字段属性
对象点该字段属性会重复走数据库 但是你一旦点了非括号内的字段 就不走数据库了
 # res = models.Book.objects.all()  # django orm查询都是惰性查询
    # print(res)


    # res = models.Book.objects.values('title')
    # print(res)
    # for r in res:
    #     print(r.title)

    # res = models.Book.objects.only('title')  # 這些對象内部只有title屬性
    # # print(res)
    # for r in res:
    #     # print(r.title)
    #     print(r.price)    # 内部会重新遍历,寻找价格
    """
    only作用
        括号内传字段 得到的结果是一个列表套数据对象 该对象内只含有括号内指定的字段属性
        对象点该字段属性是不会走数据库的 但是你一旦点了非括号内的字段 也能够拿到数据
        但是是重新走的数据库查询吧
    """

    # res = models.Book.objects.defer('title')  # defer与only互为反关系
    # for r in res:
    #     print(r.title)
    """
    defer与only相反
        括号内传字段 得到的结果是一个列表套数据对象 该对象内没有括号内指定的字段属性
        对象点该字段属性会重复走数据库 但是你一旦点了非括号内的字段 就不走数据库了
    """
View Code

selected_related与prefetch_related

selected_related

内部是连表操作 现将关系表全部链接起来 之后再一次性查询出来 封装到对象中
数据对象之后在获取任意表中的数据的时候都不需要再走数据库了 因为全部封装成了对象的属性

select_related括号内只能传外键字段 并且不能是多对多字段 只能是一对多和一对一
select_related(外键字段1__外键字段2__外键字段3...)

prefetch_related
prefetch_related内部是子查询 但是给你的感觉是连表操作
内部通过子查询将外键管理表中的数据页全部给你封装到对象中
之后对象点当前表或者外键关联表中的字段也都不需要走数据库了
优缺点比较
select_related连表操作 好处在于只走一次sql查询
耗时耗在 连接表的操作 10s

prefetch_related子查询 走两次sql查询
耗时耗在 查询次数 1s
 # select_related和prefetch_related
    # res = models.Book.objects.get(pk=1)
    # print(res.publish.name)

    # res = models.Book.objects.select_related('publish')
    # for r in res:
    #     print(r.publish.name)
    #     print(r.publish.addr)
    """
    内部是连表操作 现将关系表全部链接起来 之后再一次性查询出来 封装到对象中
    数据对象之后在获取任意表中的数据的时候都不需要再走数据库了 因为全部封装成了对象的属性
    
    select_related括号内只能传外键字段 并且不能是多对多字段 只能是一对多和一对一
    select_related(外键字段1__外键字段2__外键字段3...)
    """

    # prefetch_related
    # res = models.Book.objects.prefetch_related('publish')
    # # print(res)
    #
    # for r in res:
    #     print(r.publish.name)

    """
    prefetch_related内部是子查询 但是给你的感觉是连表操作
    内部通过子查询将外键管理表中的数据页全部给你封装到对象中
    之后对象点当前表或者外键关联表中的字段也都不需要走数据库了
    """
    """
    优缺点比较
    select_related连表操作 好处在于只走一次sql查询
        耗时耗在 连接表的操作  10s
        
    prefetch_related子查询  走两次sql查询
        耗时耗在 查询次数      1s
    """
View Code

django orm如何开启事务操作

事务的四大特性(ACID)

  原子性

  一致性

  隔离性

  持久性

start transaction
rollback
commit

代码:

# django orm开启事务操作
from django.db import transaction
with transaction.atomic():
    # 在with代码块中执行的orm语句同属于一个事务
    pass

# 代码块运行结束 事务就结束了  事务相关的其他配置 你可以百度搜搜看

MTV与MVC模型

MTV   django号称是MTV框架

  M:models

  T:templates

  V:views

MVC

  M:models

  V:views

  C:controller  控制器(路由分发  urls.py)

本质:MTV本质也是MVC

BMS  图书管理系统

  

猜你喜欢

转载自www.cnblogs.com/ludingchao/p/12172611.html