初识Django(七):Model(模型)总述

目录

模型(Model)简介

绑定数据库

Model类的定义及使用

1 Model类定义

2 Model建立数据库表

3 Model类数据的增删查改

#多数据库使用

1 指定路由类

#2 多app设置路由

3 覆写路由类函数

结语


注:以下的属性/函数列表都是选的一些常用的,还有其他属性/函数,请另外查找资料。

模型(Model)简介

Django中的模型类可以看做对数据库中的表的另一种显示方法。与直接创建并操作数据库不同,django提供了另外一种更简单的方式在后端对数据进行操作,也就是:django提供了一系列函数让你在直接操作数据,而不需要关注数据库方面的内容,这种方法被称为对象关系映射(Object Relational Mapping,ORM)。(但是我们还需要注意的是,django的model并没有它介绍的这么精密,有些操作仍然需要我们直接在数据库进行,比如说django不会关注model类里改变的列,也没办法在model里对表重命名,所以还是学学SQL语句吧,不会吃亏的)

使用模型类还有一个额外的好处,那就是:你大体上不需要关注你使用的数据库的类型,只需要在settings.py(你使用的django项目的设置文件)中绑定数据库就行了,可以是MySQL,Oracle,也可以使用django自带的数据库Sqlite。(还有一个需要注意的点,不是所有SQL语句都对sqlite数据库有效,比如重命名列,但是我仍然认为使用sqlite有很多好处,利大于弊)

总而言之,Model是一个有关数据库与django交互的类。

绑定数据库

很多人应该都习惯用MySQL了,所以我把绑定数据库提到最前讲。

打开项目的设置文件,找到DATABASES:

DATABASES = {

    'default': {#数据库在代码中的名字

        'ENGINE': 'django.db.backends.sqlite3',#解析数据库的引擎,目前我知道的是它支持sqlite,MySQL,oracle,postgresql

        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),#数据库文件的位置

    }

}

这是django自带的sqlite数据库的设置,如果你要绑定MySQL,还需要添加一些。并且,ORM并不会创建数据库文件,数据库文件需要你自己创建并添加位置到设置文件,但是ORM可以为你在数据库文件中创建表格并对数据进行操作。你可以在DATABASE中添加这样的对象(实际情况根据你自己的数据库更改):

Model类的定义及使用

'sql': 

{ 

    'ENGINE': 'django.db.backends.mysql',

    'NAME': 'mysql_name', 

    'HOST': '127.0.0.1', # 数据库地址

    'PORT': 1111, # 端口 

    'USER': 'root',  # 数据库用户名

    'PASSWORD': '123456', # 数据库密码

}

1 Model类定义

首先,Model类依附于app而存在,这应该不难理解。同时我们再回想一下http协议的本质——数据的传递。我们的界面无论写的多么美观,其核心就是传递数据,不是么?所以我认为Model类是app的重中之重。

Model类默认定义在app目录下的models.py文件里,一个Model类对应着一张SQL表,类里的每一个由models.xxxxField()函数赋值的类属性都对应着表里的一个字段,而赋值的函数不同,也表明了字段类型的不同。常用的字段类型函数如下:

  • -IntegerField():整数
  • -CharField(max_length=最大长度):字符串
  • -DateField():日期,设置auto_now_add=True则其自动为创建时间,设置auto_now=True则其为最后一次修改后保存的时间。(很推荐设置这个,django内置的时间转换让其十分方便,如果想深入了解请看前面关于settings.py的讲解。

还有一些字段函数通用参数:

  • -null:是否允许为None
  • -blank:是否允许为空
  • -db_column:如果存在则替换属性名为列名,不存在则属性名为列名
  • -db_index:是否创建索引
  • -default:默认取值
  • -primary_key:是否为主键
  • -unique:取值是否唯一

#关于Model的内部类Meta,它可以用于存储一些描述Model行为的属性:

  • -abstract:是否为抽象类(也就是创建表)
  • -app_label:如果你的Model并不定义在models.py里,你需要设置其指向此Model的app
  • -db_table:与上文的db_column类似,存在则替换Model类名作为表名
  • -ordering:排序依据,可为[属性名’](按此属性正序),[-‘属性名’](按此属性倒序),[?属性名](按此属性随机排序,这是谁想的,小天才

最后还有一个值得注意的是,Model类生成的表默认会有一个从1自增长的整数字段id,但是其经常会失去“自增长”的功能,需要你自己赋值(存疑)。

例1 定义一个描述文章的Model类:

class Article(models.Model):

# Article表 docname文章名 datecreate创建日期 datelast最后一次修改日期 id文章id 

    docname=models.CharField(max_length=40,blank=False)

    datecreate=models.DateTimeField(auto_now_add=True)#设置datecreate字段为创建日期

    datelast=models.DateTimeField(auto_now=True)#设置datelast为最后一次修改日期

    objects=models.Manager()

    class Meta():#倒序排列

        ordering=('-datecreate',)

        #id=models.AutoField(primary_key=True) id会被自动创建

        def __str__(self):#返回描述信息

            return self.docname

2 Model建立数据库表

首先我们要让django根据Model类创建migrations文件。manage.py目录下打开cmd,输入python manage.py makemigrations,然后django会列出创建的表,打开应用目录下migrations文件夹可以看到多出了几个描述数据库的文件。然后原位置cmd输入python manage.py migrate,将migrations文件里的变化修改到数据库文件内,至此,数据库对应的表已经建立完毕。

3 Model类数据的增删查改

我使用的是manage.py shell在后台修改数据,听说django自带的app admin可以实现在前端修改数据,但是我觉得不太安全而且有些额外的麻烦,所以我们不讲这段。

manage.py目录下打开cmd,输入python manage.py shell打开shell,然后我们可以平时编程一样输入,关于Model类的增删查改函数如下(他们也可以用于视图传递数据到模版):

  • -Model类.objects.create(字段属性=初值…):创建类
  • -Model类.objects.get(条件1,…):获取一个Model对象,符合所有条件(结果大于或者小于都会报错)
  • -Model类.objects.filter(条件1,…):返回一个符合所有条件的对象的列表
  • -Model对象.delete()删除此对象
  • -Model对象.属性=值:给Model对象赋值,也就是修改对象的字段值
  • -Model对象.save():如果之前修改了对象值就要使用save函数,它同时会更新对象的最后一次修改时间

ORM是支持模糊查询和切片的(请参考列表切片),如果需要模糊查询,你可以在作为条件的属性后面添加以下后缀:

  • -__contains:包括
  • -__gt:大于
  • -__gte:大于等于
  • -__le:小于
  • -__startswith:以开头

#多数据库使用

在上面的绑定数据库中,你可以绑定一个及以上的数据库,但是如果绑定了一个以上的数据库,我们对ORM的使用也会发生变化,因为我们在操作之前得告诉django我们希望操作的是哪一个数据库。

1 指定路由类

假定你已经绑定了两个数据库default与mysql1。接下来,我们在项目的设置文件下添加DATABASE_ROUTERS项,并设定它的值为指向你项目下项目子文件夹下设置路由的文件(由你自己创建命名)下的路由类(自己命名):

DATABASE_ROUTERS=['djangoexample.MyRouters.MyRouter']#指定路由类

例子里我在项目子文件夹“djangoexapmle”下创建了“MyRouters.py”,然后创建了类“MyRouter”作为路由类。

#2 多app设置路由

如果你创建了多个app,并想为其分别指定不同的数据库,你可以在设置文件下添加DATABASE_APPS_MAPING:

DATABASE_APPS_MAPPING={

    'app_name' : 'database_name',

    'app1' : 'sql1',

    'app2' : 'sql2',

}

3 覆写路由类函数

为什么是“覆写”呢?因为在路由类中,只有特定名称的函数才能发挥其作用,帮助django选择合适的数据库。

主要使用的django路由函数有以下四个(django官网对我这的网络太慢了而且我英语不好就没上官网仔细找,粗略的看没看到):

  • -db_for_read(model,**hints):Model对象读时使用的数据库,返回db的名字
  • -db_for_write(model,**hints):Model对象写时使用的数据库,返回db的名字
  • -db_for_relation(obj1,obj2,**hints):是否允许两个对象关联到数据库,返回布尔值
  • -db_for_migrate(db,app,model_name=None,**hints):对于某个app,是否允许其对次数据库db执行migrate命令,返回布尔值

对于路由类的写法没有明确的规定,只要遵循规则返回就行。但是我还是给出一个我认为比较好的写法,就拿db_for_write函数举例(其实你粗略地写写覆盖db_for_read和db_for_write就行了):

def db_for_read(self, model, **hints):#model是传入的model对象

    if hasattr(model, '_database'):#这里判断model对象里是否有字段_database,也就是如果你要使用这种方式就要在声明此model类时添加属性_database,并指定其为要存放到的数据库名。

        return model._database

    return 'default'#如果没有此字段就读取默认的数据库,需要自己取值

结语

恭喜你学完了django的基础部分。学会了这些内容就已经足够部署一个基础的django应用到服务器了。如果你要学习ajax、中间件等更加深入的内容,请期待我后续的教程(一年之后的我只能说,这句话的意思是太监了)。

你可能感兴趣的:(django,数据库,sqlite,mysql)