zoukankan      html  css  js  c++  java
  • <Django> MVT三大块之Models(模型)

    1.ORM(对象-关系-映射)---面向对象,不需要面向SQL语句

    • 根据对象的类型生成表结构
    • 将对象、列表的操作,转化成SQL语句
    • 将SQL语句查询的结果转化成对象、列表

      目的:实现数据模型与数据库的解耦-----减少基于数据库的维护

      效果:这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动

         Django中的模型包含存储数据的字段和约束,对应着数据库中唯一的表

      支持:主流的关系型数据库

      

    链接到Mysql

    ①在mysql中创建数据库

    mysql -u root -p
    

      

     create database test2 default charset utf8; 

    当然用Navicat更快

    在Setting.py中配置mysql信息

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'test2',
            'USER': 'root',
            'PASSWORD': '',
            'HOST': 'localhost',
            'PORT': '3306',
        }
    }
    

     

    2. 建立模型类(models.py) 

    属性的类型确定:
    当前选择数据库支持的字段(核心)
    渲染管理表单的默认html控件
    在管理站点最低限度验证(要求整数,日期等验证)
    django不写不写自动生成主键列,可以直接写主键列就不会自动生成
    命名规则:
    不能使用保留字
    不能使用多个下划线(会与查询的标识符冲突)
    字段类型:
    django.db.models.fields
    重要数据:
    逻辑删除,不做物理删除
    定义方法,定义属性isDelete,类型是BooleanField,默认False
    字段类型:
    AutoField:主键自动增长,可以自己设定
    BooleanField:true/false,默认表单样式CheckboxInput
    NullBooleanField:null/true/false
    CharField(max_length=字符长度):字符串,默认表单样式TextInput
    TextField:大文本,超过4000,默认表单样式Textarea
    IntegerField:整数
    DecimalField(max_digits=None,decimal_places=None):浮点数,
    参数max_digits:位数的总数
    参数decimal_places:小数点后的数字位数
    FloatField:浮点数
    DateField(auto_now=False,auto_now_add=False):datetime.data表示日期
    参数auto_now:如果为true,表示最近一次修改时间
    参数auto_now_add:如果为true,表示添加时间
    TimeField:同DateField参数,datetime.time表示时间
    DateTimeField:datetime.datetime,表示日期和时间(常用)
    FileField:上传文件路径(一般不用)
    ImageField:继承FileField,对上传文件进行检验,确保是image(一般不用)
    字段选项(字段约束):
    null:如果为true,空值以null存到数据库
    blank:如果为true,表单验证,允许空白
    db_column:字段名称指定,如果不指定,就是属性名称
    db_index:如果是true,在表中建立索引
    primary_key:若为true,则该字段会成为主键字段
    unique:唯一约束
    关系:
    ForeignKey:外键,一对多,放在多的那端
        怎么找到外键对应的值
        
        

    ManyTOManyField:多对多,放在字段定义的两端
    OneToOneField:一对一,放在任意一端
    from django.db import models
    
    
    # Create your models here.
    
    class BookInfo(models.Model):
    	# 书名
    	btitle = models.CharField(max_length=20)
    	# 发布日期,数据库中的字段名db_column
    	bpub_date = models.DateTimeField(db_column='pub_date')
    	# 阅读量
    	bread = models.IntegerField(default=0)
    	# 评论数
    	bcomment = models.IntegerField(default=0, null=False)
    	# 逻辑删除
    	isDelete = models.BooleanField(default=False)
    
    	# 元选项
    	class Meta:
    		# 表名字
    		db_table = 'bookinfo'
    		# 默认排序规则(会增加数据库的开销)
    		ordering = ['id']
    
    	def __str__(self):
    		return "%s" % self.btitle
    
    
    class HeroInfo(models.Model):
    	# 英雄名称
    	hname = models.CharField(max_length=20)
    	# 性别
    	hgender = models.BooleanField(default=True)
    	# 英雄描述
    	hcontent = models.CharField(max_length=100)
    	# 属于哪本书
    	hBook = models.ForeignKey("BookInfo", on_delete=models.CASCADE, )
    	# 逻辑删除
    	isDelete = models.BooleanField(default=False)
    
    	def __str__(self):
    		return "%s" % self.hname

    生成迁移文件(生成上述表结构对应的SQL语句)
    python manage.py makemigrations
    
    
    

     如果使用的是python3会直接报错

      

    原因:django 连接mysql默认驱动是MySQLdb,MySQLdb没有支持python3的版本,如果使用python3.x版本时,django连接mysql的方法
    需要在setting同级目录的__init__.py文件中写入
    import pymysql
    pymysql.install_as_MySQLdb()
    
    
    

     (使用mysqlclient代替MySQLdb,mysqlclient项目在github上的地址为 https://github.com/PyMySQL/mysqlclient-python,该项目fork MySQLdb,加入了对python3的支持)

    使用前需要先安装, 然后在生成迁移文件

    pip install mysqlclient

     

    生成迁移(生成表)

    python manage.py migrate
    

     去数据库可以看到,生成了很多表

    bookinfo表的结构


    说明:不需要面临数据库进行操作,直接操作模型类就可以影响数据库
    应用:代表项目的一部分功能,将功能分开,增加代码的重用性

    插入数据



    3.模型成员(从models.Model继承的对象)
    objects:Manage类型对象(Django定义好的类),负责和数据库交互--------这东西就是ORM核心

    管理器作用:与数据库做交互,就是ORM的作用,完成数据映射

    自定义管理器作用:1.更改查询集----2.创建模型类对象方法
    支持自定义管理器对象:---进行了筛选
     

    class BookInfoManager(models.Manager):
    	def get_queryset(self):
    		return super(BookInfoManager,self).get_queryset().filter(isDelete=False)  
    class BookInfo(models.Model):
    	# 管理器对象
    	# 自带的,跟object一样
    	books1 = models.Manager()
    	# 自己定义的管理器
    	books2 = BookInfoManager()
    

     在python manage.py shell中可以查询

    from booktest.models import BookInfo
    # 查询1
    BookInfo.books1.all()
    # 查询2
    BookInfo.books2.all()
    

    4.快速创建对象(模型类的创建方法)

    在管理器类中定义一个对象方法,

    class BookInfoManager(models.Manager):
    	def get_queryset(self):
    		return super(BookInfoManager, self).get_queryset().filter(isDelete=False)
    
    	def create(self, btitle, bpub_date):
    		b = BookInfo()
    		b.btitle = btitle
    		b.bpub_date = bpub_date
    		b.bread = 0
    		b.bcomment = 0
    		b.isDelete = False
    		return b
    

      

    在python manage.py shell中创建对象

    数据库中已经保存成功

    4.查询

    数据的增删改可以在Admin中处理,这里要讲的是查询数据

    4.1查询集(相当于select语句,过滤器相当于where和limit语句)

      查询集:查询的结果

      惰性执行:创建查询集不会访问数据库,调用数据,才会访问数据库(迭代,序列化,if合用,才会立即拿数据)

      过滤器:返回查询集的方法----------调用管理器中get_querset()方法(返回最原始查询计划)

        all():获取所有数据

        fiter():可以写筛选条件(类where)---获取满足条件的数据(常用)

        exclude():可以写筛选条件(类where)---获取不满足条件的数据

        order_by():排序

        values():将查询结果(只要有一个对象)构成字典,然后构成一个列表返回(相当于json)

        

      返回单个值:

        get():返回单个满足条件的对象(常用)

          未找到:抛异常

          找到多条:抛异常

        count():返回当前查询的总条数(常用)

        first():返回满足条件的第一条

        last():返回最后一条

        exists():存在返回true

      限制查询集:(不支持负数索引)---就相当于列表

         BookInfo.books2.all()[0:2]

      查询集缓存:

        将查询结果:两次循环使用同一个查询集,第二次使用缓存中的数据   

    querylist=Entry.objects.all()
    print([e.title for e in querylist])
    print([e.title for e in querylist])
    

      不缓存的情况:(子集的时候)

    query = BookInfo.objects.all()
    # 缓存
    for ... in query[0:10]
    # 不缓存
    for ... in query[11:20]
    

    4.2字段查询

       语法:属性名称__比较运算符=值

    BookInfo.books2.filter(btitle__endswith='传')
    

      不需要转义百分号%  

      filter(title__contains="%")=>where title like '%\%%'

      比较运算符:

        exact:判断相等(大小写敏感),可以省略

      

        contains:是否包含,大小写敏感

    BookInfo.books2.filter(btitle__contains='传')
    

        startswith、endswith:以value开头或结尾,大小写敏感

    BookInfo.books2.filter(btitle__endswith='传')
    

        isnull、isnotnull:是否为null(区分大小写)

    BookInfo.books2.filter(btitle__isnull=False)
    

     在前面这些比较运算符前面加字母i,意为不区分大小写,例如iexact、icontains、istarswith、iendswith

        in:范围内

    BookInfo.books2.filter(id__in=[1,2,3,4])
    

        gt、gte、lt、lte:大于、大于等于、小于、小于等于

    BookInfo.books2.filter(id__gt=2)
    

        year、month、day、week_day、hour、minute、second:对日期间类型的属性进行运算

    BookInfo.books2.filter(bpub_date__year=1980)
    BookInfo.books2.filter(bpub_date__gt=datetime(1980, 12, 31))
    

        跨关联关系的查询:处理join查询

    BookInfo.books1.filter(heroinfo__hcontent__contains='八')
    

       查询的快捷方式:pk,pk表示primary key,默认的主键是id

    5.聚合函数

    • 使用aggregate()函数返回聚合函数的值
    • 函数:Avg,Count,Max,Min,Sum

    先引入

    from django.db.models import Max
    

      

    F对象(比较两个列)

    # 引入F
    from django.db.models import F
    # 阅读量小于评论量
    list.filter(bread__lt=F('bcomment'))
    

      django支持对F()对象使用算数运算

    list.filter(bread__lt=F('bcomment')*2)
    

      F()对象中还可以写作“模型类__列名”进行关联查询

    list.filter(isDelete=F('heroinfo__isDelete'))
    

    Q对象(逻辑或)

    逻辑与如下:

    list = BookInfo.books1.filter(pk__lt=6,btitle__contains='八')

    等同于:

    list = BookInfo.books1.filter(pk__lt=6).filter(btitle__contains='八')
    

      

    from django.db.models import Q
    
     list = BookInfo.books1.filter(Q(pk__lt=4)|Q(btitle__contains='1'))
    

      

    取反

    list.filter(~Q(pk__lt=6))
    

      

  • 相关阅读:
    Reverse linked list
    Implement Queue by Two Stacks
    Min Stack
    Search a 2D Matrix
    50. Pow(x, n)
    监控hdfs的一个目录,若有新文件,spark就开始处理这个文件,可以使用spark streaming textfilestream来监控该目录
    kafka2在重启消费者以后已经提交offset回退了 什么原因(待完善)
    Hybrid Recommender Systems: Survey and Experiments
    开源实时日志分析平台
    scala为什么要清理闭包
  • 原文地址:https://www.cnblogs.com/shuimohei/p/10662641.html
Copyright © 2011-2022 走看看