到目前已经完成了留言板的前端功能,也就是一个简单的页面,后端的逻辑还没有实现,也就是与数据库的操作。
什么是ORM
ORM即Object Relational Mapping,中文是:关系对象映射。它使用类的名称来对应数据库表名称,类的属性对应
数据库中的字段,类实例对应数据库中表的一行数据。
ORM相比原生sql的优势
在不用ORM的时候,原生sql可能需要这样写:
# 创建数据库连接
db = MySQLdb.connect(user = 'root', db='test', passwd='test', host='localhost')
# 创建游标对象
cursor = db.cursor()
# 需要的sql语句
cursor.execute('SELECT * FROM test;')
# 对于fetchall()的结果做遍历,将遍历回来的结果当做数组,取第0个值name。
names = [row[0] for row in cursor.fetchall()]
db.close()这样做是可行的,但是十分麻烦且效率很低,因为只要需要操作数据库就得重复进行上面的操作。
而使用ORM,则数据库操作就像使用类的属性一样简单,且本质上会根据对接的数据库引擎,翻译成对应的sql语句;所有使用Django开发的项目无需关心程序底层使用的是MySQL、Oracle、sqlite….,如果数据库迁移,只需要更换Django的数据库引擎即可;
创建models
在message目录下创建models.py文件,在其中对我们需要的数据库字段信息进行定义:
# -*-coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class UserMessage(models.Model):
name = models.CharField(max_length=30, verbose_name=u'用户名')
email = models.EmailField(verbose_name=u'邮箱')
address = models.CharField(max_length=200, verbose_name=u'地址')
message = models.CharField(max_length=500, verbose_name=u'留言')
class Meta():
verbose_name = u'用户留言'verbose_name用于在后台进行显示。
class Meta,内嵌于 UserMessage 这个类的定义中。如果 class UserMessage 是顶格的,那么 class Meta 在它之下要缩进4个空格。它的作用是设置一些与特定模型相关的选项。如:设置ordering = ['name'],默认地都会按 name 字段排序。
UserMessage相当于定义的是表的名称,它的字段包括name、email 、address 、message 字段。
max_length表示最大长度,CharField相当于varchar类型,必须指明最大长度。EmailField在表中表现为varchar,但是他提供CharField不具备的邮件地址合法性验证的功能。
models的其他特性
- models.ForeignKey # 外键
- models.DateTimeField # 时间字段
- models.IntegerField # 整型
- models.IPAddressField # IP地址
- models.FileField # 上传文件
- models.ImageField # 图片
ctrl按住+左键点击models 进入之后点击fields拖到文件开始可以看到所有字段:
__all__ = [str(x) for x in (
'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',
)]
null=True,blank=True指明字段可以为空,defalut = ” “指定默认值。如:
name = models.CharField(max_length=30, null=True, blank=True, verbose_name=u'用户名')注册app
定义好模型后,其实并没有生效,因为django需要用户在settings.py中注册app。修改如下字段:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'DjangoTestProject.apps.message',
]就是在列表中最后添加了一行DjangoTestProject.apps.message,可以理解为把message引入进来。
然后点击“工具” –> “Run manage.py Task”,没问题的话就没有任何报错输出。
注意,如果有编码问题需要在文件中添加# -*-coding: utf-8 -*-在第一行或第二行。
然后依次执行下面的命令:
makemigrations message
migrate messagemakemigrations message的作用就是在app下建立 migrations目录,并记录下你所有的关于modes.py的改动。
migrate message是真正地把migrations目录中关于modes.py的改动记录到数据库中的操作。
此时,数据表创建完成了,进入Navicate可以看到新生成的数据表:
发现表名并不是模型中定义的UserMessage,在django中默认的表的名称为[app名称]_小写类名。且会自动创建一个自增长的id字段。
变更主键
message/models.py中添加字段:
object_id = models.CharField(primary_key=True, max_length=50, default="", verbose_name=u'主键')同时修改name字段,让他可以为空,默认值就是空:
name = models.CharField(max_length=20,null=True,blank=True,default="", verbose_name=u"用户名")然后点击“工具” –> “Run manage.py Task”,在命令行输入命令:
makemigrations message
migrate message 从上图可以看出,具体的操作为:删除了id字段,添加了object_id字段,编辑了name字段。
在进入Navicat中可以看到新的主键已经生成:
meta()的一些特性
之前提到,在生成表的时候默认的表名有一个app名称的前缀,如果不想加前缀,可以这么做:
class Meta():
verbose_name = u'用户留言'
db_table = 'usermessage'
这里只做试验用,不添加到代码中
在meta中也可以做排序的操作,例如按照object_id正向进行排序的话可以写成:
class Meta():
verbose_name = u'用户留言'
db_table = 'usermessage'
ordering = 'object_id'逆序就在排序的字段前加上一个 -。这里只做试验用,不添加到代码中
为了后台系统便于管理员阅读,使用下面的代码:
class Meta():
verbose_name = u'用户留言'
verbose_name_plural = u'用户留言信息'它的作用是指明复数信息,便于人阅读。否则会在后台显示用户留言信息s