Django后台管理-模型-模型管理器
后台管理
创建超级管理员
1 | python manage.py createsuperuser,按提示输入用户名、邮箱、密码 |
启动服务器,通过“127.0.0.1:8000/admin”访问,输入上面创建的用户名、密码完成登录
进入管理站点,默认可以对groups、users进行管理
管理界面本地化
编辑settings.py文件,设置编码、时区
1 2 | LANGUAGE_CODE = 'zh-Hans' TIME_ZONE = 'Asia/Shanghai' |
注册models到admin
打开booktest/admin.py文件,注册模型
1 2 3 | from django.contrib import admin from models import BookInfo admin.site.register(BookInfo) |
刷新管理页面,可以对BookInfo的数据进行增删改查操作
问题:如果在str方法中返回中文,在修改和添加时会报ascii的错误
解决:在str()方法中,将字符串末尾添加“.encode(‘utf-8’)”
模型
对象关系映射ORM(object Relational Mapping )用于面向对象语言里不同类型系统的数据之间的切换。 换句话说就是用面向对象的方式去操作数据库的创建表、增加、修改、删除、查询等操作。有点自动化的意思,把sql语句剥离,只要通过对象到数据库,或者数据库到对象。它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。
使用MySql数据库
安装pymysql
1 | pip install pymysql |
打开settings.py文件,修改DATABASES项
1 2 3 4 5 6 7 8 9 10 | DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'test2', 'USER': '用户名', 'PASSWORD': '密码', 'HOST': '数据库服务器ip,本地可以使用localhost', 'PORT': '端口,默认为3306', } } |
在models.py中定义模型类,要求继承自models.Model
把应用加入settings.py文件的installed_app项
生成迁移文件
执行迁移生成表
使用模型类进行crud操作
使用数据库生成模型类
可以自定义,也可以生成,建议自定义
1 | python manage.py inspectdb > booktest/models.py |
定义模型
在模型中定义属性,会生成表中的字段
django根据属性的类型确定以下信息:
当前选择的数据库支持字段的类型
渲染管理表单时使用的默认html控件
在管理站点最低限度的验证
django会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列
属性命名限制
不能是python的保留关键字
由于django的查询方式,不允许使用连续的下划线
定义属性
定义属性时,需要字段类型
字段类型被定义在django.db.models.fields目录下,为了方便使用,被导入到django.db.models中
使用方式
导入from django.db import models
通过models.Field创建字段类型的对象,赋值给属性
对于重要数据都做逻辑删除,不做物理删除,实现方法是定义isDelete属性,类型为BooleanField,默认值为False
字段类型
AutoField:一个根据实际ID自动增长的IntegerField,通常不指定
如果不指定,一个主键字段将自动添加到模型中
BooleanField:true/false 字段,此字段的默认表单控制是CheckboxInput
NullBooleanField:支持null、true、false三种值
CharField(max_length=字符长度):字符串,默认的表单样式是 TextInput
TextField:大文本字段,一般超过4000使用,默认的表单控件是Textarea
IntegerField:整数
DecimalField(max_digits=None, decimal_places=None):使用python的Decimal实例表示的十进制浮点数
DecimalField.max_digits:位数总数
DecimalField.decimal_places:小数点后的数字位数
FloatField:用Python的float实例来表示的浮点数
DateField[auto_now=False, auto_now_add=False]):使用Python的datetime.date实例表示的日期
参数DateField.auto_now:每次保存对象时,自动设置该字段为当前时间,用于”最后一次修改”的时间戳,它总是使用当前日期,默认为false
参数DateField.auto_now_add:当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false
该字段默认对应的表单控件是一个TextInput. 在管理员站点添加了一个JavaScript写的日历控件,和一个“Today”的快捷按钮,包含了一个额外的invalid_date错误消息键
auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果
TimeField:使用Python的datetime.time实例表示的时间,参数同DateField
DateTimeField:使用Python的datetime.datetime实例表示的日期和时间,参数同DateField
FileField:一个上传文件的字段
ImageField:继承了FileField的所有属性和方法,但对上传的对象进行校验,确保它是个有效的image
字段选项
通过字段选项,可以实现对字段的约束
在字段对象时通过关键字参数指定
null:如果为True,Django 将空值以NULL 存储到数据库中,默认值是 False
blank:如果为True,则该字段允许为空白,默认值是 False
对比:null是数据库范畴的概念,blank是表单验证证范畴的
db_column:字段的名称,如果未指定,则使用属性的名称
db_index:若值为 True, 则在表中会为此字段创建索引
default:默认值
primary_key:若为 True, 则该字段会成为模型的主键字段
unique:如果为 True, 这个字段在表中必须有唯一值
关系
ForeignKey:一对多,将字段定义在多的端中
1 2 3 4 | class Article(Bolginfo): #外健 author = models.ForeignKey('Author',verbose_name="作者") tag = models.ManyToManyField('Tag',verbose_name="标签") |
ManyToManyField:多对多,将字段定义在两端中
OneToOneField:一对一,将字段定义在任意一端中
可以维护递归的关联关系,使用’self’指定,详见“自关联”
用一访问多:对象.模型类小写_set
1 | bookinfo.heroinfo_set |
用一访问一:对象.模型类小写
1 | heroinfo.bookinfo |
访问id:对象.属性_id
1 | heroinfo.book_id |
元选项
模型元数据是“任何不是字段的数据”,比如排序选项(ordering),数据库表名(db_table)或者人类可读的单复数名称(verbose_name 和verbose_name_plural)。在模型中添加class Meta是完全可选的,所有选项都不是必须的。
Abstract 如果 abstract = True, 就表示模型是抽象基类
1 2 3 4 5 6 7 8 9 10 | #基类 class Bolginfo(models.Model): isdelete = models.BooleanField(default=False,verbose_name='逻辑删除') class Meta: abstract = True #文章 class Article(Bolginfo): pass |
Verbose_name 给对象起别名,单数形式
Verbose_name_plural 对象的复数形式,可以指定复数形式的名称
元信息db_table:定义数据表名称,推荐使用小写字母,数据表的默认名称
1 | <app_name>_<model_name> |
ordering:对象的默认排序字段,获取对象的列表时使用,接收属性构成的列表
1 2 3 4 5 | class Meta: verbose_name = '文章' verbose_name_plural = verbose_name db_table = 'article' ordering = ['id'] |
字符串前加-表示倒序,不加-表示正序
1 2 3 4 | class BookInfo(models.Model): ... class Meta(): ordering = ['-id'] |
排序会增加数据库的开销
模型管理器
objects:是Manager类型的对象,用于与数据库进行交互
当定义模型类时没有指定管理器,则Django会为模型类提供一个名为objects的管理器
支持明确指定模型类的管理器
默认管理器
管理器是Django 的模型进行数据库查询操作的接口。Django 应用的每个模型都拥有至少一个管理器。Objects是Django 模型进行数据库查询操作的接口,并用于从数据库获取实例。如果没有自定义Manager,则默认的名称为objects。Managers 只能通过模型类访问,而不能通过模型实例访问。
情况一:修改管理器返回的原始查询集:重写get_queryset()方法
1 2 3 4 5 6 | class BookInfoManager(models.Manager): def get_queryset(self): return super(BookInfoManager, self).get_queryset().filter(isDelete=False) class BookInfo(models.Model): ... books = BookInfoManager() |
情况二:向管理器类中添加额外的方法(ps:python类支持这样的写法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class BookInfoManager(models.Manager): def create_book(self, title, pub_date): book = self.model() book.btitle = title book.bpub_date = pub_date book.bread=0 book.bcommet=0 book.isDelete = False return book class BookInfo(models.Model): ... books = BookInfoManager() 调用:book=BookInfo.books.create_book("abc",datetime(1980,1,1)) 保存:book.save() |
可以调用self.create()创建并保存对象,不需要再手动save()
1 2 3 4 5 6 7 8 9 10 | class BookInfoManager(models.Manager): def create_book(self, title, pub_date): book = self.create(btitle = title,bpub_date = pub_date,bread=0,bcommet=0,isDelete = False) return book class BookInfo(models.Model): ... books = BookInfoManager() 调用:book=Book.books.create_book("abc",datetime(1980,1,1)) 查看:book.pk |