Django框架模型——基本操作

Django框架--Models

Models:模型.在这个模块中,可以定义你想要创建的存储数据的类,就可以在数据库中创建对应的表.在类中添加属性就可以在表中添加对应的字段.

操作数据库的注意点

1、在Django中的models里面在制定类的属性的时,想要对应到数据库中的对应数据类型,就需要遵守Django的语法格式.

例如:想要在数据库中添加一个长度为20的字符串类型字段.那就不能使用Python中的str类型,也不能使用sql语句中的varchar来定义,而是使用Django为我们封装好的Django语句:models.CharField(max_length=20)

因此想要通过泪来操作数据库,还需要掌握Django为我们封装好的语句.

2、在类中定义的属性不能是Python中的保留字,不能使用连续的下划线。

2、创建的类模型必须继承指定的类:models.Model.

只有继承这个类Django才会为我们自动创建数据库的表

models模型属性与数据库字段对应表.


__all__ = [
    'AutoField', 'BLANK_CHOICE_DASH', 'BigAutoField', 'BigIntegerField',
    'BinaryField', 'BooleanField', 'CharField', 'CommaSeparatedIntegerField',
    'DateField', 'DateTimeField', 'DecimalField', 'DurationField',
    'EmailField', 'Empty', 'Field', 'FieldDoesNotExist', 'FilePathField',
    'FloatField', 'GenericIPAddressField', 'IPAddressField', 'IntegerField',
    'NOT_PROVIDED', 'NullBooleanField', 'PositiveIntegerField',
    'PositiveSmallIntegerField', 'SlugField', 'SmallIntegerField', 'TextField',
    'TimeField', 'URLField', 'UUIDField',
]

以上就是咋创建数据模型是,所有可选的字段项.但是常用的有以下几个:

常用字段
字段名称    可用参数     说明 
BigIntegerField   64为最大整数
BooleanField   布尔值
CharField max_length 规定最大长度 字符串 字符串类型必须指定max_length参数
DateField

auto_now:每次对象存储时会自动更新字段事件为当前时间

auto_add_now:每次对象被创建时会被自动填入,且不会自动更新

两种参数稚嫩而过任选其一,不可同时制定

日期格式,可用于datetime.date

两种参数默认为False,指定为True时开启

DecimalField

max_digits:最大位数.

decimal_places:指定小数位数

小数,义字符串形式存储,精确度高,

常用于金融数据

EmaileField max_length:最大长度 接收电子邮件地址的数据
FloatField     浮点数,没有Decimal精确度高
IntegerField   整数,最为常用
PostiveIntegerField   正整数
SlugField  max_length:最大长度  和CharField一样,常用来指定网址
TextField     长文字格式,一般用于HTML窗体的textarea输入项目中
URLField max_length:最大长度 和CharField一样,特别用来记录完整的URL网址
AutoField   自动增长字段,一般用来设置主键
ImageField upload 指定上传的图片路径 保存上传的图片路径,在数据库中保存的是图片的路径

models字段常用属性
字段选项 说明 默认值
null 用来指定字段是否可以为空 False
blank 指定是否接受空白内容(与后台管理有关) False
choices 指定字段的可选内容.采用元组套元组的方式来指定 无.
default 指定字段默认值
help_text 字段的帮助信息
primary_key 设置主键 False
unique 设置字段为唯一值 False

db_column

指定数据库中的字段名称
db_index 为该字段添加索引 False

以上就是常用字段及常用属性的说明.大概了解之后就可以创建爱你类对象来操作数据库了.

经验:如果已经对models进行了迁移,却又修改了表结构,就需要重新进行迁移。如果没有则不需要。例如修改字段的default值、blank属性。

通过Models操作数据库

通过models中的类来操作数据库时,需要先创建模型。然后调用相应的属性和方法即可实现数据的增删改查操作。而其中最重要、使用最频繁的莫过于查了。

首先在项目的应用文件夹中的models.py文件中创建对应的类模型。笔者创建的是一个学生类。代码的演示都是在交互式环境中。这样方便我们查看结果。

在models文件中创建类对象——Student,这样会对应到数据库中的一张表,然后再类中定义相应的类属性,这会对应到表中的字段。

代码演示:

from django.db import models

# Create your models here.

############################
# 无关系测试
class Student(models.Model):
    Name = models.CharField(max_length=20)
    Age = models.IntegerField()
    Height = models.DecimalField(max_digits=5, decimal_places=2)
    Birthday = models.DateField()

在上面的代码中,我们创建了一个学生了模型,并且定义了相应的字段。指定了相应的参数。

创建好模型后,我们的数据库中并没有什么变化,因为我们还需要进行迁移操作,来让Django帮我们生成对应的sql语句,并在数据库中创建我们需要的表。

1、生成迁移文件

python manage.py makemigrations

2、迁移到数据库

python manage.py migrate

第一步执行后,会在当前应用文件夹中的migrations文件夹中创建一个迁移文件,里面保存了我们创建对象模型后的信息。

第二部执行后,就会在数据库中创建相应的表,来存储,默认表名是:应用名_类名 (本例中为:app_student)

在数据库查看对应的表可以发现表的样式为:

mysql> desc app_student;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| Name     | varchar(20)  | NO   |     | NULL    |                |
| Height   | decimal(5,2) | NO   |     | NULL    |                |
| Birthday | date         | NO   |     | NULL    |                |
| Age      | int(11)      | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

由于所有的字段我们均没有指定null参数为True,因此该表中的数据默认都是不能为空,也就是在插入数据是,每个字段的值都需指定。

另外一点就是,表中自动出现了一个id字段,并且被设置为主键、自动增长。就是Django自动创建的。

如果我们自己指定某一字段为主键,那么Django就不会自动创建该字段了。

以上执行完毕后就完成了数据表的创建,接下来就可以进行数据的操作了

进入交互式环境:python manage.py shell

 

models操作数据库——增

进入交互式环境后,首先是导入模块

from app.models import Student

1、通过对象来添加数据。


# 在交互式环境中依次输入以下代码

# 1、创建对象
stu = Student()

# 2、添加属性
stu.Name = 'Jack'
stu.Age = 18
stu.Height = 175.66
stu.Birthday = '1997-05-06'

# 调用save() 方法来保存到数据库
stu.save()

代码分析:

通过对象添加数据时,需要先创建一个空对象,然后再添加对应的属性,之后调用对象自带的save()方法即可实现像数据库中插入一条数据。

可以发现,这样操作起来要比在数据库中输入sql指令要更有可读性,而且更容易理解。这就是ORM的体现。、

2、通过类对象方法创建对象。

# 在交互式环境中输入以下指令。

# 获取数据模型管理对象
Student_objects = Student.objects

# 通过模型管理对象的create方法添加数据
stu_1 = Student.objects.create(Name='Petter', Age=20, Height=176.57, Birthday='1996-02-06')

# 打印返回的对象
print(stu_1)
print(type(stu_1))

print(stu_1.Name)

代码结果:


'Petter'


代码分析:

第一句代码是获取了一个管理器对象,这个对象就如同一个管理员,用来管理我们对数据库的操作,也可以理解为我们操作数据库的一个接口(API)。

这个管理器对象是从Student类中获得的,因此这个对象是专属于Student的。用来管理Student类的数据。

第二句我们就是用了这个对像的create方法来实例化一个对象并写入数据库,同时返回这个对象。我们使用 stu_1 接收这个对象,后面是打印这个信息来验证我们的结果。


以上就是两种创建对象的方法。想要查看在数据库中的存储情况。可以直接在数据库中进行查看。

查询对象的相关方法会在后面讲到。

 

通过models操作数据库——改

修改数据库中的数据,其实和添加数据的操作是一样的。只需要获取到数据对象后修改对象属性,然后在调用 save() 方法即可实现修改。

代码演示:

# 在交互式环境中依次输入以下代码

# 获取对象
s1 = Student,objects.get(Name='Petter')

# 查看对象信息
print(s1.Name)
print(s1.Age)
print(s1.Height)
print(s1.Birthday)
print(type(s1))

# 修改信息
s1.Name = '小王'

# 写入数据库
s1.save()


代码结果:



'Petter'
20
Decimal('176.57')
datetime.date(1996, 2, 6)


代码分析:


第一句代码使用了管理器对象的get方法来获取数据库中的数据。要特别注意的是查找的方式,我们向get方法传递了一个参数,来规定了我们要查找的数据条件。

当我们调用了该方法后,Django会帮我们转化成对应的sql语句,然后将查到的结果包装秤一个对象返回。一次你我们才可以使用该对象的方法和属性。

限制条件的传递语法:属性名=值

get方法的详细使用会在后面讲到。


通过models操作数据库——删

删除操作可以说是最简单的一种操作了。

代码演示


# 通过get方法获取对象
s1 = Student.objects.get(Name='小王')

# 调用返回对象的 delete 方法
s1.delete()

代码分析:


恩,没错,就这么简单。两步搞定,还可以糅合成一句代码,但实际上还是分两步完成。

通过模型管理器对象获取数据库中的数据,得到一个包装好的对象,然后调用该对象自带的delete方法即可实现删除操作。


通过models操作数据库——查

咳咳,敲黑板,重点来了。。。

查数据一直都是最为常用的。因此,Django也提供了非常多的查询方式,而这些查询方式都会一一对应到具体的sql语句。

在sql语句查询中,有非常多的查询方式。在Django则是通过数据模型管理器对象的相关方法进行操作的。因此就先来看看这个对象中都有哪些方法可供使用吧。

代码演示:


# 查看类对象管理器的所有方法
print(dir(Student.objects))

# 查看帮助文档
# print(help(Student.objects))

代码结果:


['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slotnames__', '__str__', '__subclasshook__', '__weakref__', '_constructor_args', '_db', '_get_queryset_methods', '_hints', '_insert', '_originating_model', '_queryset_class', '_set_creation_counter', '_update', 'aggregate', 'all', 'annotate', 'auto_created', 'bulk_create', 'check', 'complex_filter', 'contribute_to_class', 'count', 'create', 'creation_counter', 'dates', 'datetimes', 'db', 'db_manager', 'deconstruct', 'defer', 'difference', 'distinct', 'earliest', 'exclude', 'exists', 'extra', 'filter', 'first', 'from_queryset', 'get', 'get_or_create', 'get_queryset', 'in_bulk', 'intersection', 'iterator', 'last', 'latest', 'model', 'name', 'none', 'only', 'order_by', 'prefetch_related', 'raw', 'reverse', 'select_for_update', 'select_related', 'union', 'update', 'update_or_create', 'use_in_migrations', 'using', 'values', 'values_list']

 

Help on Manager in module django.db.models.manager object:

class Manager(BaseManagerFromQuerySet)
 |  Method resolution order:
 |      Manager
 |      BaseManagerFromQuerySet
 |      BaseManager
 |      builtins.object
 |
 |  Data and other attributes defined here:
 |
 |  __slotnames__ = []
 |
 |  ----------------------------------------------------------------------
 |  Methods inherited from BaseManagerFromQuerySet:
 |
 |  aggregate(self, *args, **kwargs)
 |      Returns a dictionary containing the calculations (aggregation)
 |      over the current queryset
 |
 |      If args is present the expression is passed as a kwarg using
 |      the Aggregate object's default alias.
 |
 |  annotate(self, *args, **kwargs)
 |      Return a query set in which the returned objects have been annotated
 |      with extra data or aggregations.
 |
 |  bulk_create(self, *args, **kwargs)
 |      Inserts each of the instances into the database. This does *not* call
 |      save() on each of the instances, does not send any pre/post save
 |      signals, and does not set the primary key attribute if it is an
 |      autoincrement field (except if features.can_return_ids_from_bulk_insert=True).
 |      Multi-table models are not supported.
 |
 |  complex_filter(self, *args, **kwargs)
 |      Returns a new QuerySet instance with filter_obj added to the filters.
 |
 |      filter_obj can be a Q object (or anything with an add_to_query()
 |      method) or a dictionary of keyword lookup arguments.
 |
 |      This exists to support framework features such as 'limit_choices_to',
 |      and usually it will be more natural to use other methods.
 |
 |  count(self, *args, **kwargs)
 |      Performs a SELECT COUNT() and returns the number of records as an
 |      integer.
 |
 |      If the QuerySet is already fully cached this simply returns the length
 |      of the cached results set to avoid multiple SELECT COUNT(*) calls.
 |
 |  create(self, *args, **kwargs)
 |      Creates a new object with the given kwargs, saving it to the database
 |      and returning the created object.
 |
 |  dates(self, *args, **kwargs)
 |      Returns a list of date objects representing all available dates for
 |      the given field_name, scoped to 'kind'.
 |
 |  datetimes(self, *args, **kwargs)
 |      Returns a list of datetime objects representing all available
 |      datetimes for the given field_name, scoped to 'kind'.
 |
 |  defer(self, *args, **kwargs)
 |      Defers the loading of data for certain fields until they are accessed.
 |      The set of fields to defer is added to any existing set of deferred
 |      fields. The only exception to this is if None is passed in as the only
 |      parameter, in which case all deferrals are removed (None acts as a
 |      reset option).
 |
 |  difference(self, *args, **kwargs)
 |
 |  distinct(self, *args, **kwargs)
 |      Returns a new QuerySet instance that will select only distinct results.
 |
 |  earliest(self, *args, **kwargs)
 |
 |  exclude(self, *args, **kwargs)
 |      Returns a new QuerySet instance with NOT (args) ANDed to the existing
 |      set.
 |
 |  exists(self, *args, **kwargs)
 |
 |  extra(self, *args, **kwargs)
 |      Adds extra SQL fragments to the query.
 |
 |  filter(self, *args, **kwargs)
 |      Returns a new QuerySet instance with the args ANDed to the existing
 |      set.
 |
 |  first(self, *args, **kwargs)
 |      Returns the first object of a query, returns None if no match is found.
 |
 |  get(self, *args, **kwargs)
 |      Performs the query and returns a single object matching the given
 |      keyword arguments.
 |
 |  get_or_create(self, *args, **kwargs)
 |      Looks up an object with the given kwargs, creating one if necessary.
 |      Returns a tuple of (object, created), where created is a boolean
 |      specifying whether an object was created.
 |
 |  in_bulk(self, *args, **kwargs)
 |      Returns a dictionary mapping each of the given IDs to the object with
 |      that ID. If `id_list` isn't provided, the entire QuerySet is evaluated.
 |
 |  intersection(self, *args, **kwargs)
 |
 |  iterator(self, *args, **kwargs)
 |      An iterator over the results from applying this QuerySet to the
 |      database.
 |
 |  last(self, *args, **kwargs)
 |      Returns the last object of a query, returns None if no match is found.
 |
 |  latest(self, *args, **kwargs)
 |
 |  none(self, *args, **kwargs)
 |      Returns an empty QuerySet.
 |
 |  only(self, *args, **kwargs)
 |      Essentially, the opposite of defer. Only the fields passed into this
 |      method and that are not already specified as deferred are loaded
 |      immediately when the queryset is evaluated.
 |
 |  order_by(self, *args, **kwargs)
 |      Returns a new QuerySet instance with the ordering changed.
 |
 |  prefetch_related(self, *args, **kwargs)
 |      Returns a new QuerySet instance that will prefetch the specified
 |      Many-To-One and Many-To-Many related objects when the QuerySet is
 |      evaluated.
 |
 |      When prefetch_related() is called more than once, the list of lookups to
 |      prefetch is appended to. If prefetch_related(None) is called, the list
 |      is cleared.
 |
 |  raw(self, *args, **kwargs)
 |
 |  reverse(self, *args, **kwargs)
 |      Reverses the ordering of the QuerySet.
 |
 |  select_for_update(self, *args, **kwargs)
 |      Returns a new QuerySet instance that will select objects with a
 |      FOR UPDATE lock.
 |
 |  select_related(self, *args, **kwargs)
 |      Returns a new QuerySet instance that will select related objects.
 |
 |      If fields are specified, they must be ForeignKey fields and only those
 |      related objects are included in the selection.
 |
 |      If select_related(None) is called, the list is cleared.
 |
 |  union(self, *args, **kwargs)
 |
 |  update(self, *args, **kwargs)
 |      Updates all elements in the current QuerySet, setting all the given
 |      fields to the appropriate values.
 |
 |  update_or_create(self, *args, **kwargs)
 |      Looks up an object with the given kwargs, updating one with defaults
 |      if it exists, otherwise creates a new one.
 |      Returns a tuple (object, created), where created is a boolean
 |      specifying whether an object was created.
 |
 |  using(self, *args, **kwargs)
 |      Selects which database this QuerySet should execute its query against.
 |
 |  values(self, *args, **kwargs)
 |
 |  values_list(self, *args, **kwargs)
 |
 |  ----------------------------------------------------------------------
 |  Methods inherited from BaseManager:
 |
 |  __eq__(self, other)
 |      Return self==value.
 |
 |  __hash__(self)
 |      Return hash(self).
 |
 |  __init__(self)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |
 |  __ne__(self, other)
 |      Return self!=value.
 |
 |  __str__(self)
 |      Return "app_label.model_label.manager_name".
 |
 |  all(self)
 |
 |  check(self, **kwargs)
 |
 |  contribute_to_class(self, model, name)
 |
 |  db_manager(self, using=None, hints=None)
 |
 |  deconstruct(self)
 |      Returns a 5-tuple of the form (as_manager (True), manager_class,
 |      queryset_class, args, kwargs).
 |
 |      Raises a ValueError if the manager is dynamically generated.
 |
 |  get_queryset(self)
 |      Returns a new QuerySet object.  Subclasses can override this method to
 |      easily customize the behavior of the Manager.
 |
 |  ----------------------------------------------------------------------
 |  Class methods inherited from BaseManager:
 |
 |  from_queryset(queryset_class, class_name=None) from builtins.type
 |
 |  ----------------------------------------------------------------------
 |  Static methods inherited from BaseManager:
 |
 |  __new__(cls, *args, **kwargs)
 |      Create and return a new object.  See help(type) for accurate signature.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from BaseManager:
 |
 |  __dict__
 |      dictionary for instance variables (if defined)
 |
 |  __weakref__
 |      list of weak references to the object (if defined)
 |
 |  db
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes inherited from BaseManager:
 |
 |  auto_created = False
 |
 |  creation_counter = 14
 |
 |  use_in_migrations = False


代码分析:


第一句的打印接过是一个列表,里面列出了所有可调用的方法。

第二句则是打印了整个帮助文档中的内容。

方法很多,常用的有以下几种:

管理器常用方法
函数名 作用 返回结果
filter 返回满足条件的数据 查询集QuerySet
exclude 返回不满足条件的数据 查询集QuerySet
 aggregate 调用统计函数 字典
all 返回所有数据 查询集QuerySet
count 返回数据对象个数 Int
create 创建数据对象并写入数据库(使用关键字传参) 创建的数据对象
exists 判断查询集中是否有数据对象 布尔值
first 返回查询集中的第一个对象

数据对象

last 返回查询集的最后一个对象 数据对象
get 根据条件返回一个数据对象,若查不到,或查到多个对象,抛出异常  
update 将查询集中的所有对象的数据统一更新成指定数据(使用关键字传参:字段=值)  
values 将查询集中的所有对象改为字典形式进行显示。{字段:字段值。。。} 查询集QuerySet
order_by 将查询集的结果按照传递的进来的字段进行排序。默认为升序,前面加上负号为降序 查询集QuerySet
     
     
     
     
     
   

 

以上是常用的管理器内置方法,查询集中也有很多一样的用法。也就是说,返回结果是查询集类型的数据时,可以继续使用上面的函数进行多重筛选、过滤。最终得到你想要的结果

当然,只有函数还是不行的,sql查询语句中有多种多样的查询语句,在Dajngo中自然有着对应的语句。这就需要一些运算符

比较运算符及用法
比较运算符 解释 示例

exact

iexact

相等运算符(大小写敏感)

相等运算符(忽略大小写)

filter(id__exact=1)    ——查询 id 为 1 的数据(exact可以省略)

同上,但忽略大小写   i :ignore

contains

icontains

包含运算符(大小写敏感)

包含运算符(忽略大小写)

filter(Name__contains='c')    ——查询Name字段中包含c的数据

同上,但忽略大小写   i :ignore

startswith

istartswith

判断运算符(大小写敏感)

判断运算符(忽略大小写)

filter(Name__startswith='A')    ——查询Name字段以A开头的数据

同上,但忽略大小写   i :ignore

endswith

iendswith

判断运算符(大小写敏感)

判断运算符(忽略大小写)

filter(name__endswith='A')    ——查询Name以A结尾的数据

同上,但忽略大小写   i :ignore

isnull 空值运算符 filter(Name__isnull=True)    ——查询Name字段为空值的数据
in 包含运算符 filter(id__in=[1,5,8])    ——查询id字段为1 5 8 的数据
gt、lt、lte、gte 大于、小于、大于等于、小于等于 filter(id__gte=20)    ——查询id大于等于20的数据

year month day

hour minute second

week_day

年、月、日、是、分、秒、星期

filter(lasttime__year=2017)    ——查询lasttime字段年份为2017年的数据

pk primary_key 主键的通用快捷查询方式

以上就是常用的比较运算符。在使用时可以当做筛选条件传入过滤器函数(filter、exclude等返回查询集的函数),但是这需要我们遵守Django为我们设定好的设定规则

条件格式:属性名__比较运算符=值。

Django会自动帮我们吧我们的筛选条件翻译成对应的sql语句。例如过滤函数中的条件救护被翻译为where语句。

此外还有一点就是查询集切片操作。filter、all、exclude函数反悔的查询集中,是可以使用切片来取值。但是索引不能为负,且返回的结果是一个新的查询集对象。这种操作对应到sql语句中的limit

例如:fltter(pk__gt=5)[2:5]    查询主键值大于5的数据,并且取出其中的第三、四、五个数据(下标从零开始)组成一个新的查询

集,并返回该查询集,如果没有满足的数据,则返回空集。


Q对象、F对象

1、Q对象

作用:用于添加查询条件之间的逻辑关系——and or not。也可以使用 & | ~ 操作。

注意:使用前需要先导入该类!

from django.db.models import Q

示例:filter(Q(id__gt=5)|Q(Name__contains='小'))  查询id字段大于5或Name字段中包含 “小” 的数据。

示例 filter(~Q(Name__contains='小'))  查询Name字段不包含 “小” 的数据。

过滤器中的条件默认是与的逻辑关系,此时不需要使用Q也能查询到正确的结果。若需要使用到其他关系,则需要先导入Q对象,然后将多个条件放入Q对象中,多个Q对象之间使用逻辑操作符连接即可。若涉及到优先级的问题,只需要添加上对应的括号即可。

2、F对象

作用:用于类属性之间的比较。

注意:使用前需要先导入F对象

from django.db.models import F

示例:filter(Height__gt=F('Weight'))    查询字段Height值大于字段Weight值的数据。

F对象用于类属性之间的比较,因为默认情况下,条件表达式的左边会被看做类属性,而不用加上引号来说明这是一个字符串。

但是等号右边的数据会被当做一个Python对象来处理。即使写的是类属性名称,也会被当做一个变量来处理。加上引号也只是被当做了一个字符串来处理。因此,为避免这类情况,需要使用F对象来明确表是右边数据是一个类属性。


聚合函数

SQL语句中不仅有各种查询语句,还包含了各种统计函数供我们使用。相应的。Django也为我们提供了接口。

聚合函数
函数名 作用 示例
Count 统计数量 aggregate(Count('Name'))
Max 最大值 aggregate(Max('Age'))
Min 最小值 aggregate(Min('Height'))
Sum 求和 aggregate(Sum('Age'))
Avg 平均值 aggregate(Avg('Age'))

以上就是聚合函数的说明及使用方法。需要注意的是,使用聚合函数需要放到 aggregate() 函数中使用。此外,所有的函数都不会统计对应字段为空值的数据。但会统计大小为零的数据。

注意:使用以上函数前都需要先导入才嗯呢该使用

from django.db.models import Count, Avg, Sum, Max, Min


查询集特性

1、惰性求值

当我们在获取数据库中的数据时,通常会使用一个变量来存储获取的数据结果。此时,Django并没有真正的去数据库查找数据。只有当我们在使用了获取出来的数据时(打印、运算等操作)才会到数据库中获取数据。

代码示例:

from app.models import Student

# 查询数据,保存到变量中
all_student = Student.objects.all()

# 上面那一句,并不会真正的去数据库查找数据。因为我们并没有使用数据。

# 使用数据(打印)
for i in all_student:
    print(i.Name)

代码分析:


第一句执行完,在数据库的日志中并不会有相应的操作执行。

第二句执行的时候,才会到数据库去查找数据。


2、缓存查询

当我们已经查询过数据时,下次再次使用到该结果时,使用的其实是缓存的结果,如果在第二次使用前进行了改动,例如修改属性值,添加数据,那么我们从原来的结果中获取到的数据仍然是之前查询到的结果。

代码演示:


from app.models import Student

# 获取所有学生数据
all_studnet = Student.objects.all()

# 打印数据
for i in all_student:
    print(i.Name)


# 添加数据到数据库
Student.objects.create(Name='test', Age=15, Height=167.55, Birthday='1998-01-06')

for i in all_student:
    print(i.Name)




代码分析:

代码结果不在列出。最终结果就是两次打印的数据结果都一样。我们中途添加到数据库的数据并没有显示出来。说明第二次使用到 all_student 变量时,并不会重新到数据库中再次进行查找。而是使用上一次的结果。


 

你可能感兴趣的:(Django)