Models:模型.在这个模块中,可以定义你想要创建的存储数据的类,就可以在数据库中创建对应的表.在类中添加属性就可以在表中添加对应的字段.
1、在Django中的models里面在制定类的属性的时,想要对应到数据库中的对应数据类型,就需要遵守Django的语法格式.
例如:想要在数据库中添加一个长度为20的字符串类型字段.那就不能使用Python中的str类型,也不能使用sql语句中的varchar来定义,而是使用Django为我们封装好的Django语句:models.CharField(max_length=20)
因此想要通过泪来操作数据库,还需要掌握Django为我们封装好的语句.
2、在类中定义的属性不能是Python中的保留字,不能使用连续的下划线。
2、创建的类模型必须继承指定的类:models.Model.
只有继承这个类Django才会为我们自动创建数据库的表
__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 指定上传的图片路径 | 保存上传的图片路径,在数据库中保存的是图片的路径 |
字段选项 | 说明 | 默认值 |
---|---|---|
null | 用来指定字段是否可以为空 | False |
blank | 指定是否接受空白内容(与后台管理有关) | False |
choices | 指定字段的可选内容.采用元组套元组的方式来指定 | 无. |
default | 指定字段默认值 | 无 |
help_text | 字段的帮助信息 | 无 |
primary_key | 设置主键 | False |
unique | 设置字段为唯一值 | False |
db_column |
指定数据库中的字段名称 | 无 |
db_index | 为该字段添加索引 | False |
以上就是常用字段及常用属性的说明.大概了解之后就可以创建爱你类对象来操作数据库了.
经验:如果已经对models进行了迁移,却又修改了表结构,就需要重新进行迁移。如果没有则不需要。例如修改字段的default值、blank属性。
通过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
进入交互式环境后,首先是导入模块
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 接收这个对象,后面是打印这个信息来验证我们的结果。
以上就是两种创建对象的方法。想要查看在数据库中的存储情况。可以直接在数据库中进行查看。
查询对象的相关方法会在后面讲到。
修改数据库中的数据,其实和添加数据的操作是一样的。只需要获取到数据对象后修改对象属性,然后在调用 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方法的详细使用会在后面讲到。
删除操作可以说是最简单的一种操作了。
代码演示
# 通过get方法获取对象
s1 = Student.objects.get(Name='小王')
# 调用返回对象的 delete 方法
s1.delete()
代码分析:
恩,没错,就这么简单。两步搞定,还可以糅合成一句代码,但实际上还是分两步完成。
通过模型管理器对象获取数据库中的数据,得到一个包装好的对象,然后调用该对象自带的delete方法即可实现删除操作。
咳咳,敲黑板,重点来了。。。
查数据一直都是最为常用的。因此,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的数据,并且取出其中的第三、四、五个数据(下标从零开始)组成一个新的查询
集,并返回该查询集,如果没有满足的数据,则返回空集。
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 变量时,并不会重新到数据库中再次进行查找。而是使用上一次的结果。