Models概述
Model是Django中的模型层,用来构建和操纵Web应用的数据。
Django通过Models来管理、构建应用程序的数据,Models是数据单一、明确的信息源,它包含数据库中存储的所有字段。简而言之,每个Model映射一个数据库中的表。
Django中使用ORM来操作数据库,因此不需要使用SQL语句对数据库进行操作,而是使用类和类的对象来进行数据库操作。
由于Model涉及到了数据库操作,django默认数据库为sqlite3,因此,如果要使用mysql,需要先配置mysql数据库。
ORM:对象关系映射,实现了对象和数据库之间的映射,隐藏了数据访问的细节,不需要编写SQL语句.
特点
- 1.每个Model都是继承于
django.db.models.Model
类,因此如在创建Model时,需要导入该模块包:
from django.db import models
- 2.Model中的每个属性都代表一个数据库字段。
1.创建Model
在Django中,Model在每个应用的model.py中进行创建。要创建一个model,只需在对应应用的model.py中,创建一个继承于models.Model的类,该类经过migrate后将会映射为数据库中的一张表,类中的每个属性代表数据库表中的字段:
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=40)
age = models.IntegerField(null=False)
number = models.IntegerField(unique=True)
2.将Model映射到数据库中
创建好model后,需要将该model映射成为数据库中对应的表,这时需要用到如下两个命令:
python manage.py makemigrations
该命令会根据检测到的Model是否更改来创建新的迁移文件;
python manage.py migrate
该命令根据生成的迁移文件创建数据表,以保持同步。
现在通过以上两个命令进行数据库的映射:
(.py3env) $ python manage.py makemigrations
(.py3env) $ python manage.py migrate
此时说明在数据库中已经创建了一张表,表名格式为:应用名_model名,如该例中应用名为person,因此会生成person.student表,我们可以进入mysql中查看其表结构:
mysql> desc person_student;
+--------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(40) | NO | | NULL | |
| age | int(11) | NO | | NULL | |
| number | int(11) | NO | UNI | NULL | |
+--------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
需要注意的是,在定义Model之前,必须确保在项目配置文件的INTALLED_APPS
列表中已经添加了该Model所在的应用:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls.apps.PollsConfig', #添加app
]
migrate
命令将会查看INSTALLED_APPS
列表来创建数据表。
3.字段类型
字段是Model中最重要、也是唯一需要的部分,这些字段将会映射为数据库中对应的字段。也就是说,数据库表中存储的字段都是通过Model中来定义,在Model中,每个字段被定义为Model类的属性,且都是Field
类的实例,如上例中的CharField
,IntegerField
……
注意:字段定义不能和ModelAPI中已有的标识符重复,以免冲突;
常用Field及其参数
Django中定义Model时的每个字段类型都继承自Field类,以下是常用字段。
CharField(max_length=None, **options)
对应数据库中的varchar类型。
max_length
:指定字段的长度,必须指定该参数。
IntegerField(**options)
对应数据库中的int类型
DateTimeField(auto_now=False, auto_now_add=False, **options)
代表Python中的datetime.datetime
类实例,对应数据库中的datetime类型。
- auto_now:每次保存对象时是否自动设置为当前时间,如果设置为True,则在Model.save()时自动更新,适用于”last modify”。
- auto_now_add:每次创建对象时是否自动设置为当前时间,如果设置为True,则在Model.save()时自动更新,适用于”create time”。
FileField(upload_to=None, max_length=100, **options)
用于文件上传,在数据库中被创建为varchar类型的字段。
- upload_to:指定上传文件存放的目录,如:
class MyModel(models.Model):
# file will be uploaded to MEDIA_ROOT/uploads
upload = models.FileField(upload_to='uploads/')
# or...
# file will be saved to MEDIA_ROOT/uploads/2015/01/30
upload = models.FileField(upload_to='uploads/%Y/%m/%d/')
- max_length:指定最大长度,默认100.
EmailField(max_length=254, **options)
用于检查是否为有效邮箱的CharField。
FloatField()
代表Python中的float类型数据,对应数据库中的double类型。
ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options)
用于图片上传,继承了FileField的所有属性。
- upload_to:上传图片存放的路径
- height_field:表示图片高度
- width_field:表示图片宽度
ForeignKey(to, on_delete, **options)
用于创建多对一关系表。
- to:与Model相关联的Model
- on_delete:删除被ForeignKey引用的对象时指定的约束。
ManyToManyField(to, **options)
用于创建多对多关系表。
OneToOneField(to, on_delete, parent_link=False, **options)
用于创建一对一关系表。
- parent_link:如果该字段设置为True,将返回父Model的链接。
关于ForeignKey、ManyToManyField、OneToOneField这三个关系型字段,以后会专门进行分析。
字段可选参数
除了指定字段中的必须参数之外,每个字段中,可以传入一些可选参数作为约束,常用可选参数如下:
choices
一个给定的二元组。如:
from django.db import models
class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
null
如果设置为ture,则该字段允许为空值,默认为False。
blank
如果设置为ture,则该字段允许为空值,默认为False。
注意:这两者区别:null是和纯数据相关,null=True表示,该字段允许为NULL和空值’,null=False表示该字段不能为空;blank和验证相关,blank=true表示form验证时允许输入空值,blank=False则表示该字段必须需要一个值。
default
字段的默认值
primary_key
如果设置为true,则该字段将会被设置为主键
默认情况下,Django为每个Model提供了如下字段用于创建一个自增主键:
id = models.AutoField(primary_key=True)
如果在定义model时,显示提供了primary_key=True
,则Django不会提供自增主键了。
unique
如果设置为true,该字段在表中唯一的。
verbose_name
提供一个易读的字段名称,如果没有提供该字段,则默认为当前定义的filed字段名,并将下划线转为空格、小写转大写,指定该字段后,该字段将显示在后台或者Form表单中,对用户来说具有更好的可读性如:
nickname = models.CharField(max_length=20,verbose_name='昵称')
related_name
该属性用于关系型字段中,表示反向关联相关的Model。
4.数据库操作API
当创建好数据库后,就可以进行CRUD操作了,Django中提供了对创建的数据表进行CRUD操作的API,下面在Django Shell中通过实例,对CRUD相关API进行总结。首先需要通过python manage.py shell
来打开Django Shell。
1.添加数据
在Django中,一个model映射到数据库中的一张表,而一个model对象则代表该表中的一条记录,通过Model.save()
方法来添加数据:
$ python manage.py shell
>>> from relate.models import Student
>>> stu1 = Student(name='xiaohong',age=21,number=2014,description='good girl',time='2018-4-18',avg_score=70,classroom_id=1)
>>> stu1.save()
save()
方法相当于执行insert into table ...
的操作,此时数据库表中已成功插入一条数据。
2.更新数据
更新数据也是通过Model.save()
方法进行,如:
>>> stu1.name='Little.Hong'
>>> stu1.save()
>>>
还可以用Model.update()
来更新数据:
>>> Student.objects.filter(number=2013).update(name='Lisi')
3.查询数据
对数据库中的数据进行查询,Django中要借助于一个类——models.Manager来进行,查询时Manager会返回一个QuerySet对象,每个model至少有一个Manager,默认的Manager为objects
。
注意:manager 只能通过model类名来访问,不能通过model对象来访问,因为model对象代表的是一条记录。
QuerySet是一个表示数据库中的对象的集合。它可以有零个、一个或多个过滤器,过滤器通过给定的参数缩小查询范围,在Django中QuerySet相当于select语句。
查询所有数据:
在Manager中,all()
方法会返回当前数据库中所有对象的QuerySet,如:
>>> Student.objects.all()
<QuerySet [<Student: Student object (4)>, <Student: Student object (5)>]>
>>>
相当于select * from student;
条件查询
在QuerySet中提供了两个方法用于进行条件查询:
- filter(**kwargs):返回一个包含给定查找参数对象的新QuerySet。
- exclude(**kwargs):返回一个不包含给定查找参数对象的新QuerySet。
如查找学号为2014的学生:
>>> Student.objects.all().filter(number=2014)
<QuerySet [<Student: Student object (5)>]>
>>>
或者
>>> Student.objects.filter(number=2014)
<QuerySet [<Student: Student object (5)>]>
>>>
链式查询:
>>> Student.objects.filter(
... name='Little.Hong'
... ).exclude(
... age=23)
<QuerySet [<Student: Student object (5)>]>
>>>
或者可以将每次得到的QuerySet赋给变量进行存储,之后可以进行复用:
>>> q1 = Student.objects.filter(name='Little.Hong')
>>> q2 = q1.exclude(age=32)
>>> q3 = q2.filter(number=2012)
>>> q1
<QuerySet [<Student: Student object (5)>]>
>>> q2
<QuerySet [<Student: Student object (5)>]>
>>> q3
<QuerySet []>
>>>
查询单一对象:
通过objects、fillter等从数据库中查到了QuerySet对象,如果要获取单一对象,需要使用objects.get()方法,如:
>>> Student.objects.get(pk=5)
<Student: Student object (5)>
django在同步models时候会自动为每个表创建1个id字段==pk字段。
4.删除数据
删除数据时,使用delete()
方法,这个方法是QuerySet的方法,不是Manager的,因此使用时需要注意。如:
>>> Student.objects.filter(name='Little.Hong').delete()
(1, {'relate.Student': 1})
返回删除对象的个数和每个对象删除次数的字典。
也可以通过Model.delete()来删除:
>>> Student.objects.get(name='xiaowang').delete()
(1, {'relate.Student': 1})
注意:QuerySet.delete()仅仅是执行SQL语句,并不会执行Model.delete()
5.Meta类
在创建Model时,可以通过添加内部类Meta为Model提供元数据,如下所示:
class Student(models.Model):
GENDER_CHOICES = (
('male', '男'),
('female', '女'),
)
name = models.CharField(max_length=20, null=True, blank=True, verbose_name='姓名')
birthday = models.DateField(null=True, blank=True, verbose_name='出生年月')
mobile = models.CharField(max_length=11, verbose_name='电话')
gender = models.CharField(max_length=6, null=True, blank=True, default='male', choices=GENDER_CHOICES,verbose_name='性别')
email = models.EmailField(max_length=40,null=True, blank=True, verbose_name='邮箱')
class Meta:
verbose_name = '学生姓名'
verbose_name_plural = verbose_name
所谓的元数据,是指那些不是字段的数据,如排序、可读性字段、指定数据库中的表名……
常用元数据如下:
- db_table:指定Model的数据表名,默认为”应用名_Model”的形式.
- ordering:指定数据排序规则,如
ordering = ['pub_date']
. - verbose_name:给该Model指定一个人类易读的单数形式名称.
- verbose_name_plural:给该Model指定一个人类易读的单数形式名称.
因此,如果需要在创建Model时需要指定一些元数据,则就需要在Model中使用class Meta了。