100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Python Web框架: Django基础与项目搭建2-2

Python Web框架: Django基础与项目搭建2-2

时间:2020-12-23 23:04:23

相关推荐

Python Web框架: Django基础与项目搭建2-2

7. 数据库

ORM框架

O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思。在ORM框架中,它帮我们把类和数据表进行了一个映射,可以让我们通过类和类对象就能操作它所对应的表格中的数据。ORM框架还有一个功能,它可以根据我们设计的类自动帮我们生成数据库中的表格,省去了我们自己建表的过程。

django中内嵌了ORM框架,不需要直接面向数据库编程,而是定义模型类,通过模型类和对象完成数据表的增删改查操作。

使用django进行数据库开发的步骤如下:

配置数据库连接信息

在models.py中定义模型类

迁移

通过类和对象完成数据增删改查操作

ORM作用

1. 配置

在settings.py中保存了数据库的连接配置信息,Django默认初始配置使用sqlite数据库。

1. 使用MySQL数据库首先需要安装驱动程序

pip install PyMySQL

2. 在Django的工程同名子目录的__init__.py文件中添加如下语句

from pymysql import install_as_MySQLdbinstall_as_MySQLdb()

作用是让Django的ORM能以mysqldb的方式来调用PyMySQL

3. 修改DATABASES配置信息

DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','HOST': '127.0.0.1', # 数据库主机'PORT': 3306, # 数据库端口'USER': 'root', # 数据库用户名'PASSWORD': 'mysql', # 数据库用户密码'NAME': 'django_demo' # 数据库名字}}

4. 在MySQL中创建数据库

create database django_demo default charset=utf8;

2. 定义模型类

模型类被定义在"应用/models.py"文件中。

模型类必须继承自Model类,位于包django.db.models中。

接下来首先以"图书-英雄"管理为例进行演示。

1 定义

创建应用booktest,在models.py 文件中定义模型类。

from django.db import models#定义图书模型类BookInfoclass BookInfo(models.Model):btitle = models.CharField(max_length=20, verbose_name='名称')bpub_date = models.DateField(verbose_name='发布日期')bread = models.IntegerField(default=0, verbose_name='阅读量')bcomment = models.IntegerField(default=0, verbose_name='评论量')is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')class Meta:db_table = 'tb_books' # 指明数据库表名verbose_name = '图书' # 在admin站点中显示的名称verbose_name_plural = verbose_name # 显示的复数名称def __str__(self):"""定义每个数据对象的显示信息"""return self.btitle#定义英雄模型类HeroInfoclass HeroInfo(models.Model):GENDER_CHOICES = ((0, 'female'),(1, 'male'))hname = models.CharField(max_length=20, verbose_name='名称') hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别') hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息') hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书') # 外键is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')class Meta:db_table = 'tb_heros'verbose_name = '英雄'verbose_name_plural = verbose_namedef __str__(self):return self.hname

(1)数据库表名

模型类如果未指明表名,Django默认以小写app应用名_小写模型类名为数据库表名。

可通过db_table指明数据库表名。

(2) 关于主键

django会为表创建自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后django不会再创建自动增长的主键列。

默认创建的主键列属性为id,可以使用pk代替,pk全拼为primary key。

(3) 属性命名限制

不能是python的保留关键字。

不允许使用连续的下划线,这是由django的查询方式决定的。

定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:

属性=models.字段类型(选项)

(4)字段类型

(5) 选项

null是数据库范畴的概念,blank是表单验证范畴的

(6) 外键

在设置外键时,需要通过on_delete选项指明主表删除数据时,对于外键引用表数据如何处理,在django.db.models中包含了可选常量:

CASCADE级联,删除主表数据时连通一起删除外键表中数据

PROTECT保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据

SET_NULL设置为NULL,仅在该字段null=True允许为null时可用

SET_DEFAULT设置为默认值,仅在该字段设置了默认值时可用

SET()设置为特定值或者调用特定方法,如

from django.conf import settingsfrom django.contrib.auth import get_user_modelfrom django.db import modelsdef get_sentinel_user():return get_user_model().objects.get_or_create(username='deleted')[0]class MyModel(models.Model):user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.SET(get_sentinel_user),)

DO_NOTHING不做任何操作,如果数据库前置指明级联性,此选项会抛出IntegrityError异常

2. 迁移

将模型类同步到数据库中。

(1)生成迁移文件

python manage.py makemigrations

(2)同步到数据库中

python manage.py migrate

3. 添加测试数据

insert into tb_books(btitle,bpub_date,bread,bcomment,is_delete) values('射雕英雄传','1980-5-1',12,34,0),('天龙八部','1986-7-24',36,40,0),('笑傲江湖','1995-12-24',20,80,0),('雪山飞狐','1987-11-11',58,24,0);insert into tb_heros(hname,hgender,hbook_id,hcomment,is_delete) values('郭靖',1,1,'降龙十八掌',0),('黄蓉',0,1,'打狗棍法',0),('黄药师',1,1,'弹指神通',0),('欧阳锋',1,1,'蛤蟆功',0),('梅超风',0,1,'九阴白骨爪',0),('乔峰',1,2,'降龙十八掌',0),('段誉',1,2,'六脉神剑',0),('虚竹',1,2,'天山六阳掌',0),('王语嫣',0,2,'神仙姐姐',0),('令狐冲',1,3,'独孤九剑',0),('任盈盈',0,3,'弹琴',0),('岳不群',1,3,'华山剑法',0),('东方不败',0,3,'葵花宝典',0),('胡斐',1,4,'胡家刀法',0),('苗若兰',0,4,'黄衣',0),('程灵素',0,4,'医术',0),('袁紫衣',0,4,'六合拳',0);

3. 演示工具使用

1. shell工具

Django的manage工具提供了shell命令,帮助我们配置好当前工程的运行环境(如连接好数据库等),以便可以直接在终端中执行测试python语句。

通过如下命令进入shell

python manage.py shell

导入两个模型类,以便后续使用

from booktest.models import BookInfo, HeroInfo

2. 查看MySQL数据库日志

查看mysql数据库日志可以查看对数据库的操作记录。 mysql日志文件默认没有产生,需要做如下配置:

sudo vi /etc/mysql/mysql.conf.d/f

把68,69行前面的#去除,然后保存并使用如下命令重启mysql服务。

sudo service mysql restart

使用如下命令打开mysql日志文件。

tail -f /var/log/mysql/mysql.log # 可以实时查看数据库的日志内容# 如提示需要sudo权限,执行# sudo tail -f /var/log/mysql/mysql.log

4. 数据库操作—增、删、改、查

1. 增加

增加数据有两种方法。

(1)save

通过创建模型类对象,执行对象的save()方法保存到数据库中。

>>> from datetime import date>>> book = BookInfo(btitle='西游记',bpub_date=date(1988,1,1),bread=10,bcomment=10)>>> book.save()>>> hero = HeroInfo(hname='孙悟空',hgender=0,hbook=book)>>> hero.save()>>> hero2 = HeroInfo(hname='猪八戒',hgender=0,hbook_id=book.id)>>> hero2.save()

(2)create

通过模型类.objects.create()保存。

>>> HeroInfo.objects.create(hname='沙悟净',hgender=0,hbook=book)<HeroInfo: 沙悟净>

2. 删除

删除有两种方法

(1)模型类对象delete

hero = HeroInfo.objects.get(id=13)hero.delete()

(2)模型类.objects.filter().delete()

HeroInfo.objects.filter(id=14).delete()

3. 修改

修改更新有两种方法

(1)save

修改模型类对象的属性,然后执行save()方法

hero = HeroInfo.objects.get(hname='猪八戒')hero.hname = '猪悟能'hero.save()

(2)update

使用模型类.objects.filter().update(),会返回受影响的行数

HeroInfo.objects.filter(hname='沙悟净').update(hname='沙僧')

4. 查询

(1)基本查询

get查询单一结果,如果不存在会抛出模型类.DoesNotExist异常。

all查询多个结果。

count查询结果数量。

>>> BookInfo.objects.all()<QuerySet [<BookInfo: 射雕英雄传>, <BookInfo: 天龙八部>, <BookInfo: 笑傲江湖>, <BookInfo: 雪山飞狐>, <BookInfo: 西游记>]>>>> book = BookInfo.objects.get(btitle='西游记')>>> book.id5>>> BookInfo.objects.get(id=3)<BookInfo: 笑傲江湖>>>> BookInfo.objects.get(pk=3)<BookInfo: 笑傲江湖>>>> BookInfo.objects.get(id=100)Traceback (most recent call last):File "<console>", line 1, in <module>File "/Users/delron/.virtualenv/dj/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_methodreturn getattr(self.get_queryset(), name)(*args, **kwargs)File "/Users/delron/.virtualenv/dj/lib/python3.6/site-packages/django/db/models/query.py", line 380, in getself.model._meta.object_namedb.models.DoesNotExist: BookInfo matching query does not exist.>>> BookInfo.objects.count()6

(2)过滤查询

实现SQL中的where功能,包括

filter过滤出多个结果exclude排除掉符合条件剩下的结果get过滤单一结果

对于过滤条件的使用,上述三个方法相同,故仅以filter进行讲解。

过滤条件的表达语法如下:

属性名称__比较运算符=值# 属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线

(1)相等

exact:表示判等。

例:查询编号为1的图书。

BookInfo.objects.filter(id__exact=1)可简写为:BookInfo.objects.filter(id=1)

(2)模糊查询

contains:是否包含。

说明:如果要包含%无需转义,直接写即可。

例:查询书名包含’传’的图书。

BookInfo.objects.filter(btitle__contains='传')

startswith、endswith:以指定值开头或结尾。

例:查询书名以’部’结尾的图书

BookInfo.objects.filter(btitle__endswith='部')

以上运算符都区分大小写,在这些运算符前加上i表示不区分大小写,如iexact、icontains、istartswith、iendswith.

(3) 空查询

isnull:是否为null。

例:查询书名不为空的图书。

BookInfo.objects.filter(btitle__isnull=False)

(4) 范围查询

in:是否包含在范围内。

例:查询编号为1或3或5的图书

BookInfo.objects.filter(id__in=[1, 3, 5])

(5)比较查询

gt 大于 (greater then)gte 大于等于 (greater then equal)lt 小于 (less then)lte 小于等于 (less then equal)

例:查询编号大于3的图书

BookInfo.objects.filter(id__gt=3)

不等于的运算符,使用exclude()过滤器。

例:查询编号不等于3的图书

BookInfo.objects.exclude(id=3)

(6)日期查询

year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算

例:查询1980年发表的图书。

BookInfo.objects.filter(bpub_date__year=1980)

例:查询1980年1月1日后发表的图书。

BookInfo.objects.filter(bpub_date__gt=date(1990, 1, 1))

(3)F和Q对象

① F对象

之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢? 答:使用F对象,被定义在django.db.models中。

语法如下:

F(属性名)

例:查询阅读量大于等于评论量的图书。

from django.db.models import FBookInfo.objects.filter(bread__gte=F('bcomment'))

可以在F对象上使用算数运算。

例:查询阅读量大于2倍评论量的图书。

BookInfo.objects.filter(bread__gt=F('bcomment') * 2)

② Q对象

多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字

例:查询阅读量大于20,并且编号小于3的图书。

BookInfo.objects.filter(bread__gt=20,id__lt=3)或BookInfo.objects.filter(bread__gt=20).filter(id__lt=3)

如果需要实现逻辑或or的查询,需要使用Q()对象结合|运算符,Q对象被义在django.db.models中

语法如下:

Q(属性名__运算符=值)

例:查询阅读量大于20的图书,改写为Q对象如下。

from django.db.models import QBookInfo.objects.filter(Q(bread__gt=20))

Q对象可以使用&、|连接,&表示逻辑与,|表示逻辑或。

例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现

BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3))

Q对象前可以使用~操作符,表示非not。

例:查询编号不等于3的图书。

BookInfo.objects.filter(~Q(pk=3))

(4)聚合查询

① 聚合函数

使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg 平均,Count 数量,Max 最大,Min 最小,Sum 求和,被定义在django.db.models中。

例:查询图书的总阅读量。

from django.db.models import SumBookInfo.objects.aggregate(Sum('bread'))

注意aggregate的返回值是一个字典类型,格式如下:

{'属性名__聚合类小写':值}如:{'bread__sum':3}

使用count时一般不使用aggregate()过滤器。

例:查询图书总数。

BookInfo.objects.count()

注意count函数的返回值是一个数字。

2. 排序

使用order_by对结果进行排序

BookInfo.objects.all().order_by('bread') # 升序BookInfo.objects.all().order_by('-bread') # 降序

(5)关联查询

① 关联查询

由一到多的访问语法:

一对应的模型类对象.多对应的模型类名小写_set

例:

b = BookInfo.objects.get(id=1)b.heroinfo_set.all()# 如果 在 hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书', related_name="heros") # 可以替换成 b.heros.all()

由多到一的访问语法:

多对应的模型类对象.多对应的模型类中的关系类属性名 例:

h = HeroInfo.objects.get(id=1)

h.hbook

访问一对应的模型类关联对象的id语法:

多对应的模型类对象.关联类属性_id

例:

h = HeroInfo.objects.get(id=1)h.hbook_id

② 关联过滤查询

由多模型类条件查询一模型类数据

语法如下:

关联模型类名小写__属性名__条件运算符=值

注意:如果没有"__运算符"部分,表示等于

例:查询图书,要求图书英雄为"孙悟空"

BookInfo.objects.filter(heroinfo__hname='孙悟空')

查询图书,要求图书中英雄的描述包含"八"

BookInfo.objects.filter(heroinfo__hcomment__contains='八')

由一模型类条件查询多模型类数据

语法如下:

一模型类关联属性名__一模型类属性名__条件运算符=值

注意:如果没有"__运算符"部分,表示等于

例:

查询书名为“天龙八部”的所有英雄。

HeroInfo.objects.filter(hbook__btitle='天龙八部')

查询图书阅读量大于30的所有英雄

HeroInfo.objects.filter(hbook__bread__gt=30)

5. 查询集 QuerySet

1. 概念

Django的ORM中存在查询集的概念。

查询集,也称查询结果集、QuerySet,表示从数据库中获取的对象集合。

当调用如下过滤器方法时,Django会返回查询集(而不是简单的列表):

all():返回所有数据。filter():返回满足条件的数据。exclude():返回满足条件之外的数据。order_by():对结果进行排序。

对查询集可以再次调用过滤器进行过滤,如

BookInfo.objects.filter(bread__gt=30).order_by('bpub_date')

也就意味着查询集可以含有零个、一个或多个过滤器。过滤器基于所给的参数限制查询的结果。

从SQL的角度讲,查询集与select语句等价,过滤器像where、limit、order by子句。

判断某一个查询集中是否有数据:

exists():判断查询集中是否有数据,如果有则返回True,没有则返回False。

2. 两大特性

(1)惰性执行

创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用。

例如,当执行如下语句时,并未进行数据库查询,只是创建了一个查询集qs

qs = BookInfo.objects.all()

继续执行遍历迭代操作后,才真正的进行了数据库的查询

for book in qs:print(book.btitle)

(2)缓存

使用同一个查询集,第一次使用时会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数。

情况一:如下是两个查询集,无法重用缓存,每次查询都会与数据库进行一次交互,增加了数据库的负载。

from booktest.models import BookInfo[book.id for book in BookInfo.objects.all()][book.id for book in BookInfo.objects.all()]

情况二:经过存储后,可以重用查询集,第二次使用缓存中的数据。

qs=BookInfo.objects.all()[book.id for book in qs][book.id for book in qs]

3. 限制查询集

可以对查询集进行取下标或切片操作,等同于sql中的limit和offset子句。

注意:不支持负数索引。

对查询集进行切片后返回一个新的查询集,不会立即执行查询。

如果获取一个对象,直接使用[0],等同于[0:1].get(),但是如果没有数据,[0]引发IndexError异常,[0:1].get()如果没有数据引发DoesNotExist异常。

示例:获取第1、2项,运行查看。

qs = BookInfo.objects.all()[0:2]

6. 管理器Manager

管理器是Django的模型进行数据库操作的接口,Django应用的每个模型类都拥有至少一个管理器。

我们在通过模型类的objects属性提供的方法操作数据库时,即是在使用一个管理器对象objects。当没有为模型类定义管理器时,Django会为每一个模型类生成一个名为objects的管理器,它是models.Manager类的对象。

1. 自定义管理器

我们可以自定义管理器,并应用到我们的模型类上。

注意:一旦为模型类指明自定义的过滤器后,Django不再生成默认管理对象objects。

自定义管理器类主要用于两种情况:

(1)修改原始查询集,重写all()方法。

① 打开booktest/models.py文件,定义类BookInfoManager

#图书管理器class BookInfoManager(models.Manager):def all(self):#默认查询未删除的图书信息#调用父类的成员语法为:super().方法名return super().filter(is_delete=False)

② 在模型类BookInfo中定义管理器

class BookInfo(models.Model):...books = BookInfoManager()

③ 使用方法

BookInfo.books.all()

(2)在管理器类中补充定义新的方法

① 打开booktest/models.py文件,定义方法create。

class BookInfoManager(models.Manager):#创建模型类,接收参数为属性赋值def create_book(self, title, pub_date):#创建模型类对象self.model可以获得模型类book = self.model()book.btitle = titlebook.bpub_date = pub_datebook.bread=0book.bcommet=0book.is_delete = False# 将数据插入进数据表book.save()return book

② 为模型类BookInfo定义管理器books语法如下

class BookInfo(models.Model):...books = BookInfoManager()

③ 调用语法如下:

book=BookInfo.books.create_book("abc",date(1980,1,1))

8. Admin站点

1. 使用Admin站点

说明:

Django能够根据定义的模型类自动地生成管理页面。

使用Django的管理模块,需要按照如下步骤操作:

管理界面本地化创建管理员注册模型类自定义管理页面

1. 管理界面本地化

在settings.py中设置语言和时区

LANGUAGE_CODE = 'zh-hans' # 使用中国语言TIME_ZONE = 'Asia/Shanghai' # 使用中国上海时间

2. 创建超级管理员

创建管理员的命令如下,按提示输入用户名、邮箱、密码。

python manage.py createsuperuser

(venv) F:\python\test_project\Coconut>python manage.py createsuperuserUsername (leave blank to use 'administrator'): admin # 超级用户的用户名Email address: admin@ # 邮箱随便写一个Password:# 输入密码Password (again):The password is too similar to the username.# 密码我写了 admin,显示太简单,不用管This password is too short. It must contain at least 8 characters.This password is too common.Bypass password validation and create user anyway? [y/N]: y # 提示是否创建,输入 y 回车Superuser created successfully.

打开浏览器,在地址栏中输入如下地址后回车。

http://127.0.0.1:8000/admin/

输入前面创建的用户名、密码完成登录。

登录成功后界面如下,但是并没有我们自己应用模型的入口,接下来进行第三步操作。

如果想要修改密码可以执行

python manage.py changepassword 用户名

3. App应用配置

在每个应用目录中都包含了apps.py文件,用于保存该应用的相关信息。

在创建应用时,Django会向apps.py文件中写入一个该应用的配置类,如

from django.apps import AppConfigclass BooktestConfig(AppConfig):name = 'booktest'

我们将此类添加到工程settings.py中的INSTALLED_APPS列表中,表明注册安装具备此配置属性的应用。

AppConfig.name属性表示这个配置类是加载到哪个应用的,每个配置类必须包含此属性,默认自动生成。

AppConfig.verbose_name属性用于设置该应用的直观可读的名字,此名字在Django提供的Admin管理站点中会显示,如

from django.apps import AppConfigclass BooktestConfig(AppConfig):name = 'booktest'verbose_name = '图书管理'

4. 注册模型类

登录后台管理后,默认没有我们创建的应用中定义的模型类,需要在自己应用中的admin.py文件中注册,才可以在后台管理中看到,并进行增删改查操作。

打开booktest/admin.py文件,编写如下代码:

from django.contrib import adminfrom booktest.models import BookInfo,HeroInfoadmin.site.register(BookInfo)admin.site.register(HeroInfo)

到浏览器中刷新页面,可以看到模型类BookInfo和HeroInfo的管理了。

点击类名称"BookInfo"(图书)可以进入列表页,默认只有一列。

在列表页中点击"增加"可以进入增加页,Django会根据模型类的不同,生成不同的表单控件,按提示填写表单内容后点击"保存",完成数据创建,创建成功后返回列表页。

在列表页中点击某行的第一列可以进入修改页,按照提示进行内容的修改,修改成功后进入列表页。在修改页点击“删除”可以删除一项。

删除:在列表页勾选想要删除的复选框,可以删除多项。

点击执行后进入确认页面,删除后回来列表页面。

5. 调整站点信息

Admin站点的名称信息也是可以自定义的。

未调整前如下图:

admin.site.site_header 设置网站页头admin.site.site_title 设置页面标题admin.site.index_title 设置首页标语

在booktest/admin.py文件中添加一下信息

from django.contrib import adminadmin.site.site_header = '王二狗书城'admin.site.site_title = '王二狗书城MIS'admin.site.index_title = '欢迎使用王二狗书城MIS'

刷新网站,效果如下

2. 调整列表页展示

调整列表页和编辑页必须先—定义与使用Admin管理类

Django提供的Admin站点的展示效果可以通过自定义ModelAdmin类来进行控制。

定义管理类需要继承自admin.ModelAdmin类,如下

from django.contrib import adminclass BookInfoAdmin(admin.ModelAdmin):pass

使用管理类有两种方式:

注册参数

admin.site.register(BookInfo,BookInfoAdmin)

装饰器

@admin.register(BookInfo)class BookInfoAdmin(admin.ModelAdmin):pass

1. 列表中的列显示哪些字段

属性如下:

list_display=[模型字段1,模型字段2,...]

打开booktest/admin.py文件,修改BookInfoAdmin类如下:

class BookInfoAdmin(admin.ModelAdmin):...list_display = ['id','btitle']

2. 页大小

每页中显示多少条数据,默认为每页显示100条数据,属性如下:

list_per_page=100

(1)打开booktest/admin.py文件,修改AreaAdmin类如下:

class BookInfoAdmin(admin.ModelAdmin):list_per_page = 2

(2)在浏览器中查看区域信息的列表页面,效果如下图:

3. "操作选项"的位置

顶部显示的属性,设置为True在顶部显示,设置为False不在顶部显示,默认为True。

actions_on_top=True

底部显示的属性,设置为True在底部显示,设置为False不在底部显示,默认为False。

actions_on_bottom=False

(1)打开booktest/admin.py文件,修改BookInfoAdmin类如下:

class BookInfoAdmin(admin.ModelAdmin):...actions_on_top = Trueactions_on_bottom = True

(2)在浏览器中刷新效果如下图:

点击列头可以进行升序或降序排列。

4. 右侧栏过滤器

属性如下,只能接收字段,会将对应字段的值列出来,用于快速过滤。一般用于有重复值的字段。

list_filter=[]

(1)打开booktest/admin.py文件,修改HeroInfoAdmin类如下:

class HeroInfoAdmin(admin.ModelAdmin):...list_filter = ['hbook', 'hgender']

(2)在浏览器中刷新效果如下图:

5. 搜索框

属性如下,用于对指定字段的值进行搜索,支持模糊查询。列表类型,表示在这些字段上进行搜索。

search_fields=[]

(1)打开booktest/admin.py文件,修改HeroInfoAdmin类如下:

class HeroInfoAdmin(admin.ModelAdmin):...search_fields = ['hname']

(2)在浏览器中刷新效果如下图:

6. 将方法作为列

列可以是模型字段,还可以是模型方法,要求方法有返回值。

通过设置short_description属性,可以设置在admin站点中显示的列名。

(1)打开booktest/models.py文件,修改BookInfo类如下:

class BookInfo(models.Model):...def pub_date(self):return self.bpub_date.strftime('%Y年%m月%d日')pub_date.short_description = '发布日期' # 设置方法字段在admin中显示的标题

(2)打开booktest/admin.py文件,修改BookInfoAdmin类如下:

class BookInfoAdmin(admin.ModelAdmin):...list_display = ['id','atitle','pub_date']

(3)在浏览器中刷新效果如下图:

方法列是不能排序的,如果需要排序需要为方法指定排序依据。

admin_order_field=模型类字段

(1)打开booktest/models.py文件,修改BookInfo类如下:

class BookInfo(models.Model):...def pub_date(self):return self.bpub_date.strftime('%Y年%m月%d日')pub_date.short_description = '发布日期'pub_date.admin_order_field = 'bpub_date'

(2)在浏览器中刷新效果如下图:

7. 关联对象

无法直接访问关联对象的属性或方法,可以在模型类中封装方法,访问关联对象的成员。

(1)打开booktest/models.py文件,修改HeroInfo类如下:

class HeroInfo(models.Model):...def read(self):return self.hbook.breadread.short_description = '图书阅读量'

(2)打开booktest/admin.py文件,修改HeroInfoAdmin类如下:

class HeroInfoAdmin(admin.ModelAdmin):...list_display = ['id', 'hname', 'hbook', 'read']

(3)在浏览器中刷新效果如下图:

3. 调整编辑页展示

1. 显示字段

属性如下:

fields=[]

(1)点击某行ID的链接,可以转到修改页面,默认效果如下图:

(2)打开booktest/admin.py文件,修改BookInfoAdmin类如下:

class BookInfoAdmin(admin.ModelAdmin):...fields = ['btitle', 'bpub_date']

(3)刷新浏览器效果如下图:

2. 分组显示

属性如下:

fieldsets=(('组1标题',{'fields':('字段1','字段2')}),('组2标题',{'fields':('字段3','字段4')}),)

(1)打开booktest/admin.py文件,修改BookInfoAdmin类如下:

class BookInfoAdmin(admin.ModelAdmin):...# fields = ['btitle', 'bpub_date']fieldsets = (('基本', {'fields': ['btitle', 'bpub_date']}),('高级', {'fields': ['bread', 'bcomment'],'classes': ('collapse',) # 是否折叠显示}))

(2)刷新浏览器效果如下图:

说明:fields与fieldsets两者选一使用。

3. 关联对象

在一对多的关系中,可以在一端的编辑页面中编辑多端的对象,嵌入多端对象的方式包括表格、块两种。

类型InlineModelAdmin:表示在模型的编辑页面嵌入关联模型的编辑。子类TabularInline:以表格的形式嵌入。子类StackedInline:以块的形式嵌入。

(1)打开booktest/admin.py文件,创建HeroInfoStackInline类。

class HeroInfoStackInline(admin.StackedInline):model = HeroInfo # 要编辑的对象extra = 1 # 附加编辑的数量

(2)打开booktest/admin.py文件,修改BookInfoAdmin类如下:

class BookInfoAdmin(admin.ModelAdmin):...inlines = [HeroInfoStackInline]

(3)刷新浏览器效果如下图:

可以用表格的形式嵌入。

(1)打开booktest/admin.py文件,创建HeroInfoTabularInline类。

class HeroInfoTabularInline(admin.TabularInline):model = HeroInfoextra = 1

(2)打开booktest/admin.py文件,修改BookInfoAdmin类如下:

class BookInfoAdmin(admin.ModelAdmin):...inlines = [HeroInfoTabularInline]

(3)刷新浏览器效果如下图:

4. 上传图片

Django有提供文件系统支持,在Admin站点中可以轻松上传图片。

使用Admin站点保存图片,需要安装Python的图片操作包

pip install Pillow

1. 配置

默认情况下,Django会将上传的图片保存在本地服务器上,需要配置保存的路径。

我们可以将上传的文件保存在静态文件目录中,如我们之前设置的static_files目录中在settings.py 文件中添加如下上传保存目录信息

MEDIA_ROOT=os.path.join(BASE_DIR,"static_files/media")

2. 为模型类添加ImageField字段

我们为之前的BookInfo模型类添加一个ImageFiled

class BookInfo(models.Model):...image = models.ImageField(upload_to='booktest', verbose_name='图片', null=True)

upload_to 选项指明该字段的图片保存在MEDIA_ROOT目录中的哪个子目录

进行数据库迁移操作

python manage.py makemigrationspython manage.py migrate

3. 使用Admin站点上传图片

进入Admin站点的图书管理页面,选择一个图书,能发现多出来一个上传图片的字段

选择一张图片并保存后,图片会被保存在**static_files/media/booktest/**目录下。

在数据库中,我们能看到image字段被设置为图片的路径

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。