五、orm设计

到目前已经完成了留言板的前端功能,也就是一个简单的页面,后端的逻辑还没有实现,也就是与数据库的操作。

什么是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相当于定义的是表的名称,它的字段包括nameemailaddressmessage 字段。

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 message

这里写图片描述

makemigrations 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


版权声明:本文为sinat_35930259原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。