这片博文来详细说明django模型的使用,涉及到django模型的创建,字段介绍,以及django模型的crud操作,以及一对一等操作。
在使用模型之前,我们首先设置数据库选项,django的默认数据库时sqlite3,这里我们设置数据库引擎为mysql。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': "webinfo", 'USER': "root", "PASSWORD": "123456", "PORT": 3306, "HOST": "10.0.102.222", } }
#这里的参数也就是连接数据库需要的参数,其中name表示的是连接到数据库的哪个库。需要注意的是除了使用django默认引擎外,其余的引擎都需要在对应的数据库上创建对应的数据库。
#MySQL创建对应的数据库语句如下!
MariaDB [mytest]> create database webinfo character set utf8;
Query OK, 1 row affected (0.01 sec)
django模型中的字段类型
熟悉MySQL数据库的话就会知道字段类型的含义,同样django中也为各种各样的信息设置了字段,选择合适的字段对数据的正确存储至关重要,这里会详细说明django中的字段类型。
首先来看一下官方文档的一个实例:在models.py中,我们写入了如下代码,这个代码创建了一个Person类,定义了两个类属性。
class Person(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40)
执行如下操作:
E:pycharmweb estmodel>python2 manage.py makemigrations Migrations for 'mysite': mysitemigrations 001_initial.py: - Create model Person #创建了模块Person E:pycharmweb estmodel>python2 manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, mysite, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying admin.0002_logentry_remove_auto_add... OK Applying contenttypes.0002_remove_content_type_name... OK Applying auth.0002_alter_permission_name_max_length... OK Applying auth.0003_alter_user_email_max_length... OK Applying auth.0004_alter_user_username_opts... OK Applying auth.0005_alter_user_last_login_null... OK Applying auth.0006_require_contenttypes_0002... OK Applying auth.0007_alter_validators_add_error_messages... OK Applying auth.0008_alter_user_username_max_length... OK Applying mysite.0001_initial... OK
在数据库中查看表:
MariaDB [webinfo]> show tables; #django会自动帮我们创建一些表,这些表适合权限认证以及日志相关的表 +----------------------------+ | Tables_in_webinfo | +----------------------------+ | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | django_admin_log | | django_content_type | | django_migrations | | django_session | | mysite_person | #这张表使我们自定义的。其中models.py中的类名对应着表名,类中的类属性对应字段名。 +----------------------------+ 11 rows in set (0.00 sec) MariaDB [webinfo]> desc mysite_person; #表名的定义方式为appname_classname, 表中自动创建了id列的主键。 +------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | first_name | varchar(30) | NO | | NULL | | | last_name | varchar(40) | NO | | NULL | | +------------+-------------+------+-----+---------+----------------+ 3 rows in set (0.01 sec) MariaDB [webinfo]>
上面的表中的字段类型为varchar对应django字段类型为CharField。CharField中的max_length=30属性表示的字段最大长度,因此在表的字段定义中定义了varchar的长度为30。通过以上的一个简单的实例,应该了解了django中字段类型的含义。
字段是模型中最重要的内容之一,也是唯一必须的部分。字段在Python中表现为一个类属性,体现了数据表中的一个列。请不要使用clean、save、delete等Django内置的模型API名字。
字段类型的作用:
- 决定数据库中对应列的数据类型(例如:INTEGER, VARCHAR, TEXT)
- HTML中对应的表单标签的类型,例如<input type=“text” />
- 在admin后台和自动生成的表单中最小的数据验证需求
这里也可以看到使用django模型比使用python的orm模型的好处。下面说明一些常见的字段类型:
官方文档中对字段类型的介绍地址: https://docs.djangoproject.com/en/2.1/ref/models/fields/#filefield
类型 说明 AutoField: 一个自动增加的整数类型字段。通常你不需要自己编写它,Django会自动帮你添加字段:id = models.AutoField(primary_key=True),这是一个自增字段,
从1开始计数。如果你非要自己设置主键,那么请务必将字段设置为primary_key=True。Django在一个模型中只允许有一个自增字段,并且该字段必须为主键! BigAutoField:(1.10新增)64位整数类型自增字段,数字范围更大,从1到9223372036854775807 BigIntegerField: 64位整数字段(看清楚,非自增),类似IntegerField ,-9223372036854775808 到9223372036854775807。在Django的模板表单里体现为一个textinput标签。 BinaryField: 二进制数据类型。使用受限,少用。 BooleanField:布尔值类型。默认值是None。在HTML表单中体现为CheckboxInput标签。如果要接收null值,请使用NullBooleanField。 CharField:字符串类型。必须接收一个max_length参数,表示字符串长度不能超过该值。默认的表单标签是input text。最常用的filed,没有之一! CommaSeparatedIntegerField: 逗号分隔的整数类型。必须接收一个max_length参数。常用于表示较大的金额数目,例如1,000,000元。 DateField: class DateField(auto_now=False, auto_now_add=False, **options)日期类型。一个Python中的datetime.date的实例。在HTML中表现为TextInput标签。
在admin后台中,Django会帮你自动添加一个JS的日历表和一个“Today”快捷方式,以及附加的日期合法性验证。两个重要参数:(参数互斥,不能共存)
auto_now:每当对象被保存时将字段设为当前日期,常用于保存最后修改时间。auto_now_add:每当对象被创建时,设为当前日期,常用于保存创建日期(注意,
它是不可修改的)。设置上面两个参数就相当于给field添加了editable=False和blank=True属性。如果想具有修改属性,请用default参数。
例子:pub_time = models.DateField(auto_now_add=True),自动添加发布时间。 DateTimeField: 日期时间类型。Python的datetime.datetime的实例。与DateField相比就是多了小时、分和秒的显示,其它功能、参数、用法、默认值等等都一样。 DecimalField: 固定精度的十进制小数。相当于Python的Decimal实例,必须提供两个指定的参数!参数max_digits:最大的位数,必须大于或等于小数点位数 。
decimal_places:小数点位数,精度。 当localize=False时,它在HTML表现为NumberInput标签,否则是text类型。
例子:储存最大不超过999,带有2位小数位精度的数,定义如下:models.DecimalField(..., max_digits=5, decimal_places=2)。 DurationField: 持续时间类型。存储一定期间的时间长度。类似Python中的timedelta。在不同的数据库实现中有不同的表示方法。常用于进行时间之间的加减运算。
但是小心了,这里有坑,PostgreSQL等数据库之间有兼容性问题! EmailField: 邮箱类型,默认max_length最大长度254位。使用这个字段的好处是,可以使用DJango内置的EmailValidator进行邮箱地址合法性验证。 FileField: class FileField(upload_to=None, max_length=100, **options)上传文件类型,后面单独介绍。 FilePathField: 文件路径类型,后面单独介绍 FloatField: 浮点数类型,参考整数类型 ImageField: 图像类型,后面单独介绍。 IntegerField: 整数类型,最常用的字段之一。取值范围-2147483648到2147483647。在HTML中表现为NumberInput标签。 GenericIPAddressField:class GenericIPAddressField(protocol='both', unpack_ipv4=False, **options)[source],IPV4或者IPV6地址,字符串形式,
例如192.0.2.30或者2a02:42fe::4在HTML中表现为TextInput标签。参数protocol默认值为‘both’,可选‘IPv4’或者‘IPv6’,表示你的IP地址类型。 NullBooleanField: 类似布尔字段,只不过额外允许NULL作为选项之一。 PositiveIntegerField: 正整数字段,包含0,最大2147483647。 PositiveSmallIntegerField: 较小的正整数字段,从0到32767。 SlugField: slug是一个新闻行业的术语。一个slug就是一个某种东西的简短标签,包含字母、数字、下划线或者连接线,通常用于URLs中。可以设置max_length参数,默认为50。 SmallIntegerField: 小整数,包含-32768到32767。 TextField: 大量文本内容,在HTML中表现为Textarea标签,最常用的字段类型之一!如果你为它设置一个max_length参数,那么在前端页面中会受到输入字符数量限制,
然而在模型和数据库层面却不受影响。只有CharField才能同时作用于两者。 TimeField: 时间字段,Python中datetime.time的实例。接收同DateField一样的参数,只作用于小时、分和秒。 URLField: 一个用于保存URL地址的字符串类型,默认最大长度200。 UUIDField: 用于保存通用唯一识别码(Universally Unique Identifier)的字段。使用Python的UUID类。在PostgreSQL数据库中保存为uuid类型,其它数据库中为char(32)。
这个字段是自增主键的最佳替代品,后面有例子展示。
注意这里有一个filefield类型的用法,暂时先空!
上面介绍了django中模型的字段类型,django中除了定义字段的类型,还有类似于mysql中约束条件一样,django对每种类型都有一些约束设置。
摘自:http://www.liujiangblog.com/course/django/97
所有的模型字段都可以接收一定数量的参数,比如CharField至少需要一个max_length参数。下面的这些参数是所有字段都可以使用的,并且是可选的。
null: 该值为True时,Django在数据库中使用NULL存储空值。默认值为False。对于保存字符串类型数据的字段,请尽量避免将此参数设为True,那样会导致两种‘没有数据’的情况,一种是NULL,另一种是‘空字符串’。在大多数情况下,使用两种方法表示没有数据时重复的,django决定使用空字符表示空值而不是NULL。
One exception is when a CharField has both unique=True and blank=True set. In this situation, null=True is required to avoid unique constraint violations when saving multiple objects with blank values.
blank: True时,字段值可以为空。默认False。和null参数不同的是,null是纯数据库层面的,而blank是验证相关的,它与表单验证是否允许输入框内为空有关,与数据库无关。
choice:它是一个可迭代的结构(比如,列表或是元组),由可迭代的二元组组成(比如[(A, B), (A, B) ...]),用来给这个字段提供选择项。 如果设置了 choices ,默认表格样式就会显示选择框,而不是标准的文本框,而且这个选择框的选项就是 choices 中的元组。如下一个实例来说明choice的用法:
gender = models.CharField(default="female", choices=(("male", u"男"), ("female", u"女")), verbose_name=u"性别",max_length=5)
#性别只有两个选项,因此这里使用了choice属性。
db_column: 该参数用于定义当前字段在数据表内的列名。如果未指定,Django将使用字段名作为列名。
db_index: 该参数接收布尔值。如果为True,数据库将为该字段创建索引。
db_tablespace: 用于字段索引的数据库表空间的名字,前提是当前字段设置了索引。默认值为工程的DEFAULT_INDEX_TABLESPACE设置。如果使用的数据库不支持表空间,该参数会被忽略。
default: 字段的默认值,可以是值或者一个可调用对象。如果是可调用对象,那么每次创建新对象时都会调用。设置的默认值不能是一个可变对象,比如列表、集合等等。lambda匿名函数也不可用于default的调用对象,因为匿名函数不能被migrations序列化。
注意:在某种原因不明的情况下将default设置为None,可能会引发intergyerror:not null constraint failed,即非空约束失败异常,导致python manage.py migrate失败,此时可将None改为False或其它的值,只要不是None就行。
editable: 如果设为False,那么当前字段将不会在admin后台或者其它的ModelForm表单中显示,同时还会被模型验证功能跳过。参数默认值为True。
error_messages: 用于自定义错误信息。参数接收字典类型的值。字典的键可以是null、 blank、 invalid、 invalid_choice、 unique和unique_for_date其中的一个。
help_text: 额外显示在表单部件上的帮助文本。使用时请注意转义为纯文本,防止脚本攻击。
primary_key:
如果你没有给模型的任何字段设置这个参数为True,Django将自动创建一个AutoField自增字段,名为‘id’,并设置为主键。也就是id = models.AutoField(primary_key=True)。
如果你为某个字段设置了primary_key=True,则当前字段变为主键,并关闭Django自动生成id主键的功能。
primary_key=True隐含null=False和unique=True的意思。一个模型中只能有一个主键字段!
另外,主键字段不可修改,如果你给某个对象的主键赋个新值实际上是创建一个新对象,并不会修改原来的对象。
unique:
设为True时,在整个数据表内该字段的数据不可重复。
注意:对于ManyToManyField和OneToOneField关系类型,该参数无效。
注意: 当unique=True时,db_index参数无须设置,因为unqiue隐含了索引。
注意:自1.11版本后,unique参数可以用于FileField字段。
unique_for_date
日期唯一。可能不太好理解。举个栗子,如果你有一个名叫title的字段,并设置了参数unique_for_date="pub_date",那么Django将不允许有两个模型对象具备同样的title和pub_date。有点类似联合约束。如果指向的是日期,也就是说仅仅日期是唯一的。
unique_for_month
同上,只是月份唯一。
unique_for_year
同上,只是年份唯一。
verbose_name: 暂空。
validators: 运行在该字段上的验证器的列表。