• Django笔记 —— 模型


      最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过。Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧~

      本篇笔记(其实我的所有笔记都是),并不会过于详细的讲解。因此如果有大家看不明白的地方,欢迎在我正版博客下留言,有时间的时候我很愿意来这里与大家探讨问题。(当然,不能是简简单单就可以百度到的问题-.-)

      我所选用的教材是《The Django Book 2.0》,本节是模型部分,对应书中第五章。

    ------------------------------------------------------------------------------------------------------------------------------------------------

    -2、数据库安装

      要学习这一章,必须要安装数据库。

      我选用的数据库是MySQL,关于其安装,我专门写了一篇博文:Django笔记 —— MySQL安装

    -1、数据库入门

      你还需要掌握数据库的基本使用。

      本来想也写篇简介的,不过临近期末比较忙,拖了好几天了,就先暂时不写了。

      先推荐一个同学的博客,有机会我再补上自己的吧:mysql数据库安装及使用

    0、代码示例

      本节无需开篇给出代码 ^.^

    1、MTV开发模式

      前面介绍过MVC开发模式,这里回顾一下:

        Model,模型,数据存取部分,由Django数据库层处理,本章要讲述的内容。

        View,视图,选择哪些数据要显示以及怎样显示的部分,由视图和模板处理。

        Controller,控制器,根据用户输入调用视图的部分,由Django根据URLconf设置,对给定URL调用适当的Python函数。

      Django遵循MVC开发模式,因此Django可以被成为MVC框架。你可以和并不懂Django的同事说:“我们用MVC模式开发吧~”,以便交流。

      对于Django内行来说,Django也被称为MTV模式:

        Model,模型,即数据存取层。该层处理所有与数据相关的事:如何存取、如何验证有效性、包含哪些行为、数据之间的关系……

        Template,模板,即表现层。该层处理与表现相关的决定:如何在页面或其它类型文档中进行显示。

        View,视图,即业务逻辑层。该层处理前两层:包含存取模型及调取恰当模板的相关逻辑。

      显然,这种描述是为Django量身定做的,模型处理数据、模板处理显示,而视图则作为两者的桥梁。

    2、什么是模型

      之前我们学过模板,知道它是如何处理网页内容显示的;也学过视图中调用模板的部分。那么,什么是模型呢?

      简单说,就是在Python中搞了个库,库里有很多专门的类和操作函数。我们可以通过这个库,去操作数据库。这个库我们称之为模型。

      对数据库有一些了解的同学会知道,每个数据库都有其自己的一些语句去操作。在数据库中直接使用其语言操作,这才是最直接的方式。而所谓用模型去操作数据库,说白了,就是模型自动用你提供的用户登录,找到你要操作的数据库,把你写的模型中定义的一套语言,转换为对应的数据库语言并运行,从而操作数据库。

      很显然,这样绕了个圈子。不仅操作数据库多了一步,还要注意维护数据的同步。模型里面数据有变化,必须得注意同步到数据库里才行。

      既然我们绕这么个圈子,就肯定说明这个圈子绕得有好处。好处在哪儿呢?

    好处

    省去扫描数据库时严重的系统过载;

    省去编程时Python与SQL两种代码不断切换的繁琐;

    可以拓展出数据库中没有的高级数据结构,带来更高的效率和更好的代码复用;

    没有不同数据库平台(如MySQL、PostgreSQL、SQLite……)的兼容问题。

    坏处 数据同步存在两处,需要随时同步且会生成大量冗余数据。
    备注 Django提供了从现有数据库表中自动扫描生成模型的工具,这对现成的数据库很实用,第十八章会讨论。

      表中说得很清楚了,这里只再解释一点,关于“扫描数据库时严重的系统过载”:

        在数据库中执行存取等操作,都需要扫描数据库,这是很费时间的。而直接对数据库操作时,显然我们每次操作都需要扫描数据库,这对于网站来说,根本无法接受。

        而通过模型,我们可以在Python代码里面存取修改,然后只在需要的时候接触数据库,做存取等操作;至于平时,则完全可以只在Python代码里搞数据,这样就把严重的系统过载省去了。

    3、模型代码示例

      下面来看一段代码:

     1 from django.db import models
     2 
     3 # Create your models here.
     4 
     5 class Publisher(models.Model):
     6     name = models.CharField(max_length=30)
     7     address = models.CharField(max_length=50)
     8     city = models.CharField(max_length=60)
     9     state_province = models.CharField(max_length=30)
    10     country = models.CharField(max_length=50)
    11     website = models.URLField()
    12 
    13 class Author(models.Model):
    14     first_name = models.CharField(max_length=30)
    15     last_name = models.CharField(max_length=40)
    16     email = models.EmailField()
    17 
    18 class Book(models.Model):
    19     title = models.CharField(max_length=100)
    20     authors = models.ManyToManyField(Author)
    21     publisher = models.ForeignKey(Publisher)
    22     publication_date = models.DateField()

      以上代码是对一个数据库的设置,下面一一解释:

        1. 三个类(Class),创建了三个SQL表格(Table),一个类叫做一个模型

        2. 以Publisher模型为例,创建了6个属性(即表格中的字段,也就是列),属性名就是字段名,属性类型就是字段类型,括号中参数则是对字段的设置

        3. 例如CharField,就对应MySQL中的varchar;而这里的属性数据类型比MySQL中要多,很多是扩充的,例如这里Publisher中的网址类型、Author中的邮箱类型、Book中的日期类型

        4. Book模型中有一个ForeignKey类型,和Publisher类连起来了,表示Publisher是Book的外键,外键是一对一的关系,即一本书只有一个出版社,一个出版社也只能出版一本书

        5. Book模型中还有一个ManyToMany类型,和Author连起来了,建立了多对多的关系,一本书可以有多个作者,一个作者也可以写很多书

        6. 外键很特殊,后面会详细解释

        7. 这里要实现一组多对多的关系,Django会偷偷创建一个class(即表格),专门存这组关系

        8. 每个模型必须有单独的主键,我们这三个模型都没定义主键,因此Django会自动为每个模型生成一个自增长的整数主键字段,名叫 id

      这,就是一个模型的定义。

      你可以看到,这就相当于对一个数据库完全定义出来了;后面,就只剩下对它的使用了。

      注:附录B中列出了所有的字段类型和模板语法选项。

    4、模型安装

      这里先给出安装模型的步骤,后面再详细解释。

      大家跟我来做:

        1. 创建一个project,名叫five:django-admin.py startproject five

        2. 创建一个app,名叫books:python manage.py startapp books

        3. 在settings.py中设置好数据库:见开头 “-2 数据库安装” 那篇博文里面的 “5 在Django中设置”

        4. 在settings.py中设置好app:把 INSTALLED_APPS 和 MIDDLEWARE_CLASSES 中所有内容注释掉,然后在 INSTALLED_APPS 中加入 'books'

        5. 至此,设置已经完毕。下面写app中模型内容:写好models.py,代码如前面 “模型示例” 中所示

        5+. 写好之后,你可以用这个命令检查一下语法(可略):python manage.py check

        5++. 然后,你可以试试写入这个命令(这命令现在没用,只是让你试试看而已):python manage.py migrate

        6. 现在你应该知道,我们缺少migration,所以用刚才咱们写的models.py来生成:python manage.py makemigrations books

        6+. 现在,你可以试试写入这个命令(也没用,只是打印出来models.py对应的数据库内容,供你检查):python manage.py sqlmigrate books 0001

        7. 生成了migration,现在再运行 5++ 的命令就有用了:python manage.py migrate

      至此,模型已经生成并与数据库连接完毕,可以使用了。

    5、模型常用API  

      模型的API有很多,这里仅仅列出常用的。

      每个模型都有一个objects属性,被称为管理器,里面包含了所有对数据库的表格级操作。这里给出objects的一些用法:

    代码(模型名为MM) 解释 备注
    from AppName.models import MM 从app中导入MM模型(本篇文章中app的名字是'books')  
    MM.objects.all() 返回MM中所有的记录

    返回类型是QuerySet,

    是Django定义的一个类似列表的类

    MM.objects.filter(name='A', country='ZG') 返回MM中所有 name=='A' && country=='ZG' 的记录
    MM.objects.filter(name__contains='press')

    返回MM中所有 name中含有press子串 的记录

    类似的双下划线“魔术”操作还有:

      icontains(不区分大小写的contains)

      startswith、endswith

      range(自己猜猜呗~对应SQL的between查询)

    附录C描述了所有查找类型

    MM.objects.get(name='A') 返回MM中 name=='A' 的那个对象

    返回单独一个对象

    如果满足条件的对象数不为1

    则报错,错误信息有两种

      MM.MultipleObjectsReturned

      MM.DoesNotExist

    当然,你可以捕获这个异常,

    捕获的名字就是上面写的那样

    MM.objects.order_by("name", "address", "-country")

    对MM中所有记录排序,排序方式如下:

      第一关键字:name  升序

      第二关键字:address 升序

      第三关键字:country  降序

    返回类型是QuerySet,类似列表
    MM.objects.filter(country='ZG').order_by('name')

    链式语法,含义显而易见:

      找到MM中所有country=='ZG'的记录,

      按照name升序排列

     

    MM.objects.order_by('name')[0]

    MM.objects.order_by('name')[0:2]

    显示部分数据:

      把MM中所有记录按name升序排列,

      第一句仅返回其第1个;第二句仅返回其前两个。

    并不支持负索引。

    当然,你可以通过'-name'来实现~

    MM.objects.filter(name='A').update(name='App')

    MM.objects.all().update(country='China')

    仅更新某个字段:

      第一句,把MM中name=='A'的所有记录改为name=='App';

      第二句,把MM中所有记录改为country=='China'。

    注意,update()会返回一个整数值

    表示更新的记录条数

    MM.objects.get(name='B').delete()

    MM.objects.all().delete()

    删除记录:

      第一句,把MM中name=='B'的那一条删掉;

      第二句,把MM中所有记录删掉。

    注意,第二句慎用!

      另外,在模型内部还有一些可以设置的属性,举出两例:

    代码(在models.py中MM类内书写) 解释

    __unicode__(self):

        return self.name

    设定被查看时默认输出的信息:

      name属性的值

    class Meta:

        ordering = ['name']

    设定检索返回值的默认排序方式:

      按照name升序排列

    附录B中有Meta中所有参数

    5+、API使用示例

      我们是在学习,因此让我们在交互界面中使用模型:

        0. 打开shell:python manage.py shell

        1. 导入Publisher模型,创建两条数据并保存:

     1 >>> from books.models import Publisher
     2 >>> p1 = Publisher(name='A', address='Aaddr',
     3 ...     city='Acity', state_province='Asp', country='ZG',
     4 ...     website='http://www.aweb.com/')
     5 >>> p1.save()
     6 >>> p2 = Publisher.objects.create(name='B', address='Baddr',
     7 ...     city='Bcity', state_province='Bsp', country='ZG',
     8 ...     website='http://www.bweb.com/')
     9 >>> list = Publisher.objects.all()
    10 >>> list
    11 [<Publisher: Publisher object>, <Publisher: Publisher object>]

           代码很清晰,p1是创建然后保存进数据库的,p2则是直接创建并保存至数据库。

          但最后输入list无法看到内容,这是因为模型中没写如何输出。

        2. 在models.py中三个模型内添加__unicode__()函数:

     1 # add to class Publisher
     2 def __unicode__(self):
     3     return self.name
     4 
     5 # add to class Author
     6 def __unicode__(self):
     7     return u'%s %s' % (self.first_name, self.last_name)
     8 
     9 # add to class Book
    10 def __unicode__(self):
    11     return self.title

           这时候,重新打开shell(python manage.py shell)再查看list,就能看到友好的输出了:

    1 >>> from books.models import Publisher
    2 >>> list = Publisher.objects.all()
    3 >>> list
    4 [<Publisher: A>, <Publisher: B>]

           这里顺带提一句,python中编码统一采用unicode,虽然慢点,但作为脚本语言,这样省去很多麻烦,绝对值得。

          关于unicode的知识,原书中做了简单介绍,并且推荐了一个很好的网站供大家深入学习。我简单看了看,这个网站挺不错的,在这里同样推荐给大家。

      后面,再写示例也是不断使用上面的一条条语句了,这里就不再赘述。

      故此,示例部分到此结束。

    6、存疑与致歉

      这里存下一个小疑问:app中有一个admin.py,里面的备注写着让我在这里注册模型。而我并未注册,却仍可以正常使用模型,那么这个文件有何用处呢?

      另外,就是我在这里向关注我博客的同学说声抱歉!最近临近期末,这篇博文拖了很长时间,而且写得并不完善,有失水准,大家凑活着看吧。

    ------------------------------------------------------------------------------------------------------------------------------------------------

      至此,模型部分介绍完毕。

      下一篇介绍Django的管理界面——一个基于Web的数据输入和管理界面。

  • 相关阅读:
    svg使用
    人生是 立体, 不是平面, 股票大作手不太好的结局
    react 管理平台
    首页性能优化
    vue 安装插件
    python中如何对list之间求交集,并集和差集
    Java中String直接复制和new String创建对象的区别以及equals和==的区别和效率对比
    关于二叉树的总结
    Postgresql 数据库,如何进行数据备份以及导入到另外的数据库
    Java List详解,面试中应该如何解答关于List的问题
  • 原文地址:https://www.cnblogs.com/icedream61/p/4530235.html
Copyright © 2020-2023  润新知