Django学习之四:Django Model模块

python学习网 2018-08-31 11:00:03

目录

Django Model模块

model 模型 是映射数据库的表模型。通过操作model类及其实例对象,对数据库的表和记录进行相关操作。

MODEL需要在脑子里记住的基础概念

  • 每一个model都是django.db.models.Model的子类。
  • 每一个model的属性代表一个数据库的一个字段。
  • 遵照以上两点,django会自动为model生成database-acesss数据库访问API

class Meta 内嵌元数据定义类

用于自定义一些model设置

class SomeModel(models.Model):
    pass
    class Meta:
        db_table = Cust_tablename  # 自定义的映射数据库的表名;一般用自动生成的。
        abstract = False|True  # 定义该model 类是不是一个抽象类。

简单model创建实例

from django.db import models

class author(models.Model):
    name = models.CharField(max_length=32)
    age = models.SmallIntegerField()

    def __str__(self):
        return self.name

数据源配置

利用pymysql作为访问mysql数据源的驱动

  1. 在项目目录的__init__.py中添加以下代码:
import pymysql
pymysql.install_as_MySQLdb()
  1. 通过其它数据库管理工具,在数据库中创建好库。然后配置数据库:
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'proj01',
        'USER': 'zjq',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

# 'default'是必须设置的 

这样我的mysql数据源就配好了。

接着通过models在数据库中创建映射的表

命令行执行:

  1. python manage.py makemigrations [app_label [app_label...]] # 创建migrations文件
  2. python manage.py sqlmigrate app_label migration_name # 用于打印指定migration文件会执行的sql,sql不会同步执行到数据库中,只起到查看作用。
  3. python manage.py migrate [app_label] [ migration_name]

Field class

model class 定义的field属性就是对应数据库表中的字段。model class中定义的属性所绑定的是一个匹配数据库字段类型的Field class实例.
Field实例类型决定了以下东西:

  1. 数据库column字段类型。
  2. 决定了默认的HTML widget对象,这个是用在model-forms中的。
  3. 最小限度的校验约束,用于在Django's admin 页面 和 在 自动生成的model-forms中。

Field options:Field对象实例化参数

每种field 都有自己的特定的参数,参考官方文档model field refernece

每种field也有共同相同的参数:

  • null 默认是False
  • blank 默认是False
    特别注意区别null和blank;null是数据库层面的限制;blank是model层面有关校验;
  • choices 是一个可迭代的由二元元组组成的数据类型(如list,tuple等),作为该字段限制的取值集合作用;二元元组中的第一个是数据库字段中存的值,第二个主要用于form表单中展示;相当于第一个字是value,第二个值是展示。使用了choices参数,字段对应的html widget将是select box,而不再是text input。通过model实例获取展示值使用get_FIELDNAME_display()获取

  • default 设置默认值,可以是value或者callable object.
  • primary_key 设置为主键;主键是只读的,如果修改只会去创建一个新的记录。

model表示表关系

  • many-to-many: ManyToManyField; 也可以自己递归引用。通过through可以给多对多关系添加额外数据字段,这种利用的就是中间人model方式。关于中间人model参见https://docs.djangoproject.com/en/2.1/topics/db/models/#extra-fields-on-many-to-many-relationships;使用了中间人model,就不能通过many-to-many的add(),create(),set(),remove()去创建关系了。因为额外数据不能通过多对多field来创建。只能通过中间人model去创建了 但是clear是可以用的,用于删除所有关系。通过中间人model的基于下划线的查询是不受影响的。
  • one-to-one: OneToOneField; 和下面的ForeignKeyField类似。
  • many-to-one : ForeignKeyField;外键引用不一定是其它表,可以自己递归,引用自己的字段,这样可以表示出树形关系。

model.objects

objects是model class 最重要的属性,它是一个Manager,是查询操作的接口。

有关model继承

参见《Django ORM继承关系》,后面我会在我本地整理好后更新到博客。

有关通过model进行查询操作

参见《Django model making queries》,后面我会在我本地整理好后更新到博客。

关于FileField 和 ImageField 字段类型类

因为model涉及到文件的这两个字段,数据库中是不最好不存文件对象,只能存一个文件的相对路径(实质就是相对于settings.MEDIA_ROOT的配置根路径). 该文件字段对象提供了丰富的api来获取文件对象,获取文件路径,获取文件相关信息等。这就是数据库model文件字段和文件管理的映射就依靠:MEDIA_ROOT+MEDIA_URL+models.filefield值 建立起映射,从而提供给api使用,这样就可以通过model的filefield对象访问到用户上传到的文件。
主要API有:

  1. model_obj.filefield 是获取到文件对象,将会是和下面的model_obj.filefield.name值相同,是定义字段时的upload_to加上文件名。
  2. model_obj.filefield.name 是获取存在数据库中的值,就是相对路径(相对于根目录)
  3. model_obj.filefield.path 是获取到path,文件系统中的绝对路径。
  4. model_obj.filefield.url 是获取url,是通过media_url设置的url能访问到的路径。如:/media/avatars/default.png。 这里一定要区分path和url的区别,path是文件系统中的路径概念,可以是相对可以是绝对,而url是网络资源路径不是和path一一对应的。

初始化FileField需要一个upload_to参数:

class MyModel(models.Model):
    # file will be uploaded to MEDIA_ROOT/uploads  // MEDIA_ROOT是配置文件设置的filesystem的绝对路径。
    upload = models.FileField(upload_to='uploads/')
    # or...
    # file will be saved to MEDIA_ROOT/uploads/2015/01/30
    upload = models.FileField(upload_to='uploads/%Y/%m/%d/')

upload_to 参数也可以是一个可执行的,只要返回一个包含文件的路径;如果是可执行的对象,那么这个可执行就需要返回一个完整的文件名和路径,因为filefield将会用这个可执行对象返回的作为这个字段的值,这时候;这个给upload_to赋值一个路径字符串不同,后者会将字符串做为路径,将赋值的文件对象的名字和路径作为数据库中该字段对应的值。

还有一个FileField参数是storage 一个django的存储引擎对象,这个对象是handle存储和检索文件的引擎。
在获取到一个model对象后,给其filefield对象赋值文件路径字符串也可以。

FileField 和 field File

前者是一个Field类,后者是一个File类,是一个file文件对象。

当访问前者时,会得到一个后者实例。注意:在使用create_user方法创建model对象时,对应的FileField参数传入的是一个UploadedFile对象,但是从前者获的field获取值是,是得到的一个FieldFile对象。两个对象是相似但是不同的:相同的是都是文件对象,都是包裹了相同的文件stream,不同是的两者对外的api不同,两者获取的名字很可能是不同的,因为django会在创建model时,如果存在相同文件名,会修改新加如的文件名,避免文件冲突的。所以上传的文件名,存入django MEDIA_ROOT目录后,文件名字可能是会被修改的。后者File对象还有了url路径,提供给外界访问用户上传文件资源的url。

现在清楚了,FileField牵扯到了 存储对象,文件对象,系统配置MEDIA_ROOT,至于MEDIA_URL是给反查url或者获取url api用的。

django系统给了一个serve view函数,来提供访问用户的上传文件和系统的静态文件的功能。这个函数需要两个参数,一个文件的path,和文件的path相对的root路径。

还有一个UploadedFile 对象,这个对象就是form表单post上来的文件对象。对象api参考:https://docs.djangoproject.com/en/2.1/ref/files/uploads/#module-django.core.files.uploadedfile

阅读(806) 评论(0)