二、Django: 深入理解——模型

ORM:(object-relational-mapping)

1、根据对象的类型生成表结构

2、将对象、列表的操作转换为sql语句

3、将SQL语句查询到的结果转换为对象、列表

优点:减轻工作量,不需因数据库改变而修改代码




一、定义模型:

1、一个模型类在数据库中对应一张表,在模型类中定义的属性,对应该模型对照表中的一个字段

2、 定义属性:

  •     Django会为表增加自动增长的主键列,每个模型只能有一个主键列,若使用选项设置某属性作为主键列后,Django不会再生成默认的主键列。
  • 属性命名限制   1、标识符规则        2、不允许使用连续的下划线。
  • 定义属性时需字段类型,被定义在django.db.models.fields目录下 ,为方便使用,被导入到django.db.models中。通过导入form django.db import models 使用,通过models.Fields 创建字段类型的对象,赋值给属性。
  • 逻辑删除: 重要数据做逻辑删除,方法: 定义isDelete属性,类型为BooleanField,默认为False
  • 字段类型:  AutoField :根据实际ID自动增长的IntegerField,通常不指定。
  •                     CharField(max_length=字符长度) : 默认表单样式为TextInput
  •                     TextField :  大文本字段,超过4000使用,默认表单样式Textarea
  •                     IntegerField:   整数
  •                 DecimalField(max_digits=None, decimal_places=None):   小数(位数总数,小数点后位数)eg.3.14 ,(3,2)
  •                     FloatField : 浮点数
  •                     BooleanField: true / False     .默认表单CheckboxInput
  •                     NullBooleanField: null / true/ false
  •                     DateField( [auto_now=False, auto_now_add=False])

3、创建模型类

4、元选项:在模型类中定义一个Mate类,设置元信息。 

                    db_tables :  定义数据表名(小写), 默认为   项目名_类名小写

                    ordering   : 对象的默认排序字段,获取对象的列表时使用(会增加数据库开销)

                                            ordering [ ' id']   :  升序

                                            ordering [ ' -id']   :  降序

二、模型成员

1、类属性

            objects   :   是Manager类型的一个对象,与数据库进行交互。当定义模型类没有指定管理器,则Django为模型创建一个名为objects的管理器。

            自定义管理器:指定管理器之后,objects就不存在了

             自定义管理器类:模型管理器是Django的模型与数据库进行交互的接口,一个模型可有多个模型管理器。

                                         作用:  向管理器类中添加额外的方法。修改管理器返回的原始查询集合。(重写get_queryset())

eg.列出所有学生

           (1)自定义管理器前

from SC.models import Grades, Students
from django.utils import timezone
from datetime import *
Students.objects.all()

            (2)自定义管理器

# SC/models.py
class StudentsManager(models.Manager):        # 自定义管理器类
    def get_queryset(self):
        return super(StudentsManager, self).get_queryset().filter(isDelete=False)    # 过滤
class Students(models.Model):
    stuObj = models.Manager()    # 自定义管理器------>  原始查询集
    stuObj2 = StudentsManager()             # 过滤后的查询集
>>>Students.objects.all()
AttributeError: type object 'Students' has no attribute 'objects'
>>>Students.stuObj.all()
Out[5]: , , , ]>
>>>Students.stuObj2.all()        # 若把shit的 isDelete修改为 1 , 则 查询结果不会显示shit


2、创建对象 (  向数据库中添加数据)

      当创建对象时, Django不会对数据库进行读写操作,当调用save()时才与数据库交互,将对象保存在数据库表中。

        __init__方法已经在父类models.Model中使用,在自定义模型中无法使用。

        方法:  1.  在模型类中添加一个方法    

# SC\views.py
def addstudent(request):
    grade = Grades.objects.get(pk=1)
    stu = Students.createStudent("jake", 11, True, "dddddddddd", grade)
    stu.save()
    return HttpResponse("aaaaaaaaaaaaaaaaaaaaaaa")
# SC\urls.py
url(r'^addstudent/$', views.addstudent),
# SC\models.py
class Students(models.Model):
    # 定义一个类方法创建创建对象
    @classmethod
    def createStudent(cls, name, age, gender, content, grade, isD=False):
        stu = cls(sname = name, sage = age, sgender = gender, scontent = content, sgrade = grade, isDelete  =isD
            )
        return stu
             2. 在定义管理器中添加一个方法。
# SC\urls.py
url(r'^addstudent/$', views.addstudent),
# SC\views.py
def addstudent2(request):
    grade = Grades.objects.get(pk=1)
    stu = Students.stuObj2.createStudent("jake", 11, True, "dddddddddd", grade)
    stu.save()
    return HttpResponse("aaaaaaaaaaaaaaaaaaaaaaa")
# SC\models.py
class StudentsManager(models.Manager):

    def get_queryset(self):
        return super(StudentsManager, self).get_queryset().filter(isDelete=False)
    def createStudent(self, name, age, gender, content, grade, isDelete = False):
        # grade = Students()
        stu = self.model()        # 创建对象
        stu.sname = name
        stu.sage = age
        stu.sgender = gender
        stu.scontent = content
        stu.sgrade = grade
        return stu

三、模型查询

1、概述

        查询集: 从数据库中获取的对象集合

        查询集可以有多个过滤器

        过滤器就是一个函数,基于所给的参数,限制查询结果。

        从SQL角度来说, 查询集合与select 语句等价,过滤器就像where 条件

2、查询集:

        在管理器上调用过滤器方法返回查询集

        查询集经过过滤器筛选后返回新的查询集,所以可写成链式调用

        惰性执行,  创建查询集不会带来任何数据的访问, 知道调用数据时,才会访问数据。

        直接访问数据的情况 :  迭代, 序列化, 与if 合用

       返回查询集的方法 称为  过滤器 :    all(); filter(key=value, key=value)  或 filter(key=value).filter(key=value)   ;    exclude() 过滤掉符合条件的数据。   ;    order_by()  排序。  ;  values()一条数据就是一个对象(字典), 返回一个列表

        返回单个数据: get()---返回一个满足条件的对象;  first()  ; last() ; exists() : 判断查询集中是否有数据,返回True/ False.

        限制查询集: 查询集返回列表可用下标进行限制 (  下标不能是负数)

# SC/views.py   显示前五条记录
def students2(request):
    # studentsList = Students.objects.all()
    studentsList = Students.stuObj2.all()[0:5]            # 下标
    return render(request, 'SC/students.html', {"students": studentsList})
# SC/urls.py
url(r'^students2/$', views.students2),
# views.py   分页显示学生
def stupage(request, page):
    page = int(page)
    studentsList = Students.stuObj2.all()[(page - 1) * 5: page * 5]
    return render(request, 'SC/students.html', {"students": studentsList})
url(r'^stu/(\d+)/$', views.stupage),

            查询集的缓存: 每个查询集都包含一个缓存,来最小化地对数据库进行访问。在新建的查询集中,缓存首次为空,第一超对查询集求值,会发生数据缓存,Django会将查询出来的数据做一个缓存。

            字段查询: 实现了SQL中的where语句,作为方法filter() / exclude()/ get() 的参数。

                                exact/contains/startswith/endswith         (若在此四个关键字前面加 i , 表示不区分大小写)

                                isnull/isnotnull/in

                                gt/gte/it/ite      >  /  >=  /  <  / <=

                                year  / month / day / week_day / minute / second

             跨关联查询: 模型类名__属性名__比较运算符

# 查询名字中含有某个关键字的记录
def studentsearch(request):
    studentsList = Students.stuObj2.filter(sname__contains="k")
    return render(request, 'SC/students.html', {"students": studentsList})
url(r'^studentsearch/$', views.studentsearch),
# 查询名字以f开头的记录
def studentsearch(request):
    studentsList = Students.stuObj2.filter(sname__startswith="k")
# 取ID是2 4 6 8 的记录
def studentsearch(request):
    studentsList = Students.stuObj2.filter(pk_in=[2,4,6,8])
# 取最后修改日期为2017的记录
def studentsearch(request):
    studentsList = Students.stuObj2.filter(lastTime__year=2017])

grade = Grades.objects.filter(students__scontent__contains='xxx')      # 描述中带有‘xxx’这个字符的数据属于哪个班级

                聚合函数:

                        aggregate()  返回聚合函数的值.   参数: Max / Min / Sum / Avg /Count

from django.db.models import Max
maxAge = Students.stuObj2.aggregate(Max('sage'))        # 年龄最大的记录
print(maxAge)

                F对象  : 使用模型的A属性 与 B属性比较 , 还支持对象的算术运算

                Q对象: 过滤器的方法中的关键字参数,条件为And模式, 进行or查询。若只有一个Q对象,则只用于匹配。                                             ~Q 取反。

# 输出女生人数大于男生的班级
from django.db.models import F,Q
g = Grades.objects.filter(girl_num__gt=F('boy_num'))
print(g)
# 班级ID<3 或 年龄> 50的       :  studentsList = Students.stuObj2.filter(Q(pk__lte==3) | Q(sage__gt=50))

                




你可能感兴趣的:(Python)