zoukankan      html  css  js  c++  java
  • 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的数据输入和管理界面。

  • 相关阅读:
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    72. Edit Distance
    583. Delete Operation for Two Strings
    582. Kill Process
    indexDB基本用法
    浏览器的渲染原理
    js实现txt/excel文件下载
    git 常用命令
    nginx进入 配置目录时
  • 原文地址:https://www.cnblogs.com/icedream61/p/4530235.html
Copyright © 2011-2022 走看看