Django-图书管理系统开发

图书管理系统开发

Django Admin提供了对数据模型进行管理的Web网站,起到系统管理后台的作用。它通过读取开发人员建立的数据模型,快速构建出一个对数据进行管理的Web网站,可用于开发测试、简单管理等。

系统数据库建立

建立应用程序

利用前面的myproject项目,在项目中建立一个应用程序book: python manage.py startapp book。

然后到settings里面注册。

建立数据库表

book存储图书信息,publishing存储出版社信息,author存储作者相关信息,在models中输入:

from django.db import models

class book(models.Model):
    # 利用verbose_name让字段显示汉字名称
    title = models.CharField(max_length=20,verbose_name='图书名称')
    descript = models.TextField(verbose_name='书籍简介')
    publishdate = models.DateField(verbose_name='出版日期')
    # 外键,多对一关系,一定要加上on_delete属性
    publishing = models.ForeignKey(to='publishing',on_delete=models.CASCADE,verbose_name='出版社')
    # 多对多键
    author = models.ManyToManyField(to='author',verbose_name='作者')
    class Meta:
        verbose_name='图书信息'
        verbose_name_plural='图书信息'
    def __str__(self):
        return self.title+'--相关图书信息'

class publishing(models.Model):
    name = models.CharField(max_length=20,verbose_name='出版社名称')
    address = models.CharField(max_length=20,verbose_name='出版社地址')
    class Meta:
        verbose_name = '出版社信息'
        verbose_name_plural = '出版社书信息'
    def __str__(self):
        return '社名:'+self.name

class author(models.Model):
    name = models.CharField(max_length=10,verbose_name='姓名')
    email = models.EmailField(verbose_name='邮箱')
    birthday = models.DateField(verbose_name='出生日期')
    header = models.ImageField(verbose_name='作者头像')
    class Meta:
        verbose_name = '作者基本情况'
        verbose_name_plural = '作者基本情况'
    def __str__(self):
        return '作者:'+self.name

说明:

数据模型都继承自Model类,首先导入相关模块。

book中的publishing字段是外键,表示book表的记录与publishing表的记录是多对一的关系,即一本书对应一个出版社,一个出版社可以出多本书,外键必须有on_delete属性,on_delete=models.CASCADE表示级联删除,即一对多关系的一被删除,多也被删除。

class Meta指定数据模型的元数据,下面介绍几个常用的元数据:

  • verbose_name:数据模型对象的单数名,如不指定,默认用小写的数据模型名。如数据模型book的单数名默认为book。

    verbose_name='图书信息'
    
  • verbose_name_plural:数据模型对象的复数名,中文通常不区分单复数,可以和verbose_name一样。如不指定该选项,默认的复数名是verbose_name加s。

    verbose_name_plural='图书信息'
    
  • ordering:指定的排序方式,接收字段名组成的元组或列表。字段名前加-表示倒序。

    ordering = ['-publishing','author']
    
  • unique_together:联合约束,把几个字段组合在一起作为约束条件,约束是唯一的。

    unique_together=('title','author')
    

def __str__(self)函数通过return返回一个字符串,代表数据模型对象实例(相当于一条记录)的名字,相当于对象实例的别名。

author中header字段的类型是ImageField类型。Django先上传图片,然后在数据库表的字段中保存图片上传的位置。

下面介绍图片文件存储地址是如何设置的,settings中:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL='/media/'
MEDIA_ROOT=os.path.join(BASE_DIR,'image')

BASE_DIR变量通过系统路径函数取得地址/myproject/。

MEDIA_ROOT为/myproject/image/。新建文件夹image。

MEDIA_URL和MEDIA_ROOT有关联关系,前者代表URL中的地址前缀,当URL有这个前缀时,会解析为/myproject/image/。如"href=/media/test/test.jpg"会解析为"href=/myproject/image/test/test.jpg"。

设计完数据模型要生成数据库表:

python manage.py makemigrations
python manage.py migrate

外键的字段名为外键名_id。book_book_author是多对多键author字段生成的中间表。

建立系统超级用户

python manage.py createsuperuser

数据模型注册

数据模型需要注册到Django Admin后台才能被管理,在admin中输入:

from django.contrib import admin
from . import models
admin.site.register(models.book)
admin.site.register(models.publishing)
admin.site.register(models.author)

运行程序

当建立数据模型并注册时,Django Admin就可以管理数据模型对应的数据库表的数据,并且不用写任何代码就可以实现增删改查功能,而且自动通过外键、多对多键建立起数据库表之间的关系。

通过python manage.py runserver启动程序,浏览器输入地址http://127.0.0.1:8000/admin/并登录。

附加说明

在管理后台中,每个数据模型都有一个列表页面和编辑表单页面,前者列出数据表中的记录,后者用于添加、修改或删除数据表中的特定记录。

管理后台工作原理简述如下:

  • 启动程序后,Django运行admin.autodiscover()函数,这个函数到settings文件中查询INSTALLED_APPS设置。然后根据其列举的应用程序,到各个应用程序中查找一个名为admin的文件并执行里面的代码。
  • 在应用程序的admin文件中调用admin.site.register()在管理后台中注册各个数据模型,只有注册的数据模型才能在管理后台中显示。
  • Django Admin管理后台应用程序也有admin文件,管理后台应用程序定义了两个数据模型User和Groups并在admin中注册,因此管理页面中能显示User和Groups。
  • Django Admin管理后台实际上是一个Django应用程序,有自己的数据模型、模板文件、视图文件等。

图书管理系统完善

部分设置

设置中文

LANGUAGE_CODE = 'zh-hans'   # 让页面显示中文
TIME_ZONE = 'Asia/shanghai' # 中文格式的时间

设置图片文件路径

图片能够在网页显示是因为在HTML文件中指定了路径,Django程序运行时通过这个指定的路径找到图片文件,所以要在路由系统中设定寻找方向:

from . import settings
from django.conf.urls.static import static
urlpatterns = [
    path('admin/',admin.site.urls),
] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

说明:

首先导入静态文件处理相关文件然后通过static()函数指定一个对应关系,有两个参数,一个是URL路径前缀,一个是路径前缀代表的地址。这两个参数在settings中已经设置。将static函数的返回值加在列表项后即可实现静态文件路径设置。

页面功能完善

Django Admin管理后台系统会针对每一个数据模型生成列表页面和修改页面,我们完善系统的方式也是针对这两种页面。

Django提供的ModelAdmin类就是针对这两类页面进行定制的类,在这个类中的设置会改变页面的功能与外观。配置编写ModelAdmin类的代码通常保存在每个应用程序的admin.py文件中。

from django.contrib import admin
from . import models
class bookadmin(admin.ModelAdmin):
    # 用出版日期作为导航查询字段
    date_hierarchy = 'publishdate'
    # 设置字段无值时显示的内容
    empty_value_display = '-无值-'
    # 设置author字段的选择方式为水平扩展选择
    filter_horizontal = ('author',)
    # 以下代码在页面上对字段进行分组显示或布局
    fieldsets = (
        (
            '图书信息',
            {'fields': (('title', 'publishdate'), 'publishing', 'author')}),
        (
            '图书简介',
            {'classes': ('collapse',), 'fields': ('descript',)}),
    )
    # 自定义一个字段
    def descript_str(self, obj):
        # 对字段进行切片,取前20个字符
        return obj.descript[:20]
    # 设置自定义字段名字
    descript_str.short_description = '简介'
    # 设置过滤导航字段
    list_filter = ('title', 'publishing', 'author')
    # 设置查询的字段
    search_fields = ('title', 'publishing__name', 'author__name')
    # 列表显示字段
    list_display = ('title', 'descript_str', 'publishdate', 'publishing',)
    # 显示查询到的记录数
    show_full_result_count = True
    # 设定每页显示6条数据
    list_per_page = 6
admin.site.register(models.book, bookadmin)

说明:

代码定义了bookadmin类,这个类继承于admin.ModelAdmin,在这个类中我们可以通过设置类的各种属性来定制数据管理页面的功能与外观。

影响列表页面的属性介绍如下:

  • date_hierarchy:根据指定的日期型字段,为页面创建一个时间导航栏,赋值类型是元组类型。

    # 用出版日期作为导航查询字段
    date_hierarchy = 'publishdate'
    
  • list_display:指定显示在列表页面上的字段。如果不设置这个属性,列表页面只显示一列,内容是每个数据模型对象的__str__()函数的返回值。

    # 列表显示字段
    list_display = ('title', 'descript_str', 'publishdate', 'publishing',)
    
  • search_fields:在列表页面添加一个文本框,这个属性需要以元组数据类型赋值,元组中每个字段都可以作为模糊查询的条件,被搜索的字段一般是CharField和TextField类型。也可以通过双下划线关联到另一个表的外键、多对多键字段。

    # 设置查询的字段
    search_fields = ('title', 'publishing__name', 'author__name')
    
  • list_display_links:指定用于链接修改页面的字段,设置方式与list_display格式一样,默认情况,list_display列表中的第一个元素被作为指向修改页面的链接。如果设置为None则没有链接,将无法跳转到修改页面。

    list_display_links = ('title','descript_str')
    
  • list_filter:设置list_filter属性,在列表页面的右侧栏增加过滤导航功能,实现基于字段的过滤功能。

    # 设置过滤导航字段
    list_filter = ('title', 'publishing', 'author')
    
  • list_editable:指定在列表页面中可以被编辑的字段,指定的字段将显示为文本框,可修改后直接批量保存。不能将list_display中没有的字段、list_display_links中的字段设置为list_editable中的字段。

    list_editable = ('descript_str','publishdate')
    
  • empty_value_display:指定字段为空时(字段值为null、None、空字符等)显示的内容。

    empty_value_display = '-无值-'
    
  • show_full_result_count:用于设置是否显示查询到的记录总数。

    show_full_result_count = True
    
  • per_page:设置列表页面每页显示多少条记录。

    list_per_page = 6
    

影响修改页面的属性介绍如下:

  • fields:列出修改页面上的字段,并按列表顺序排列指定的字段。赋值时可以通过组合元组的方式,让某些字段在同一行内显示,例如下面的第二行代码,title、publishdate两个字段将排列在一行,而descript字段则排在下一行。

    # 指定在修改页面上显示的字段以及显示信息,一行显示一个字段
    fields=('title','descript','publishdate','publishing','author')
    # 把title、publishdate两个字段排在一行
    fields=(('title','publishdate'),'descript')
    
  • exclude:列出的字段不在页面上显示。

    exclude=('descript',)
    
  • fieldsets:在页面上对字段进行分组或布局,fieldsets是一个二级元组的列表。每一个二级元组代表一个<fieldset>,在HTML页面表单中生成一个<fieldset>标签。第二级元组列表格式为(name,{'fields':(field1,field2,...),'classes'😦'collapse',)}),name表示fieldsets标题,(field1,field2,...)是包含在fieldsets内的字段列表,另外还可设置fieldsets的样式。

    # 以下代码在页面上对字段进行分组显示或布局
        fieldsets = (
            (
                '图书信息',
                {'fields': (('title', 'publishdate'), 'publishing', 'author')}),
            (
                '图书简介',
                {'classes': ('collapse',), 'fields': ('descript',)}),
        )
    

    如下图,title和publishdate在一行上的原因是通过('title', 'publishdate')显示在一行。

  • filter_horizontal:主要针对多对多键字段,把选择方式改为水平扩展选择,形式如上图的作者字段中的样式。多对多键字段在django admin页面中默认显示为一个选择框。在需要从大量记录中选择时,设置字段的这个属性,页面就会对字段进行水平扩展,并提供过滤功能。

    # 设置author字段的选择方式为水平扩展选择
    filter_horizontal = ('author',)
    
  • radio_fields:外键ForeignKey字段或choices集合默认使用select标签显示。如果将这种字段属性为radio_fields,则会以radio标签组的形式展示。Radio_fields的值是字典形式,键名为字段名,键值有两个,即admin.VERTICAL、admin.HORIZONTAL,一个是垂直布局,一个是水平布局。

    # 垂直布局
    radio_fields = {'publishing':admin.VERTICAL}
    

自定义字段。前面代码中定义一个字段descript_str,定义字段采用函数的形式,传入两个参数。第一个参数是self,第二个参数代表与类bookadmin关联的数据模型对象,这里指的是book类实例对象。自定义字段函数体return的返回值就是自定义字段值。自定义字段可以通过short_description命名字段。

代码中自定义字段descript_str的值取book的数据记录的descript字段值前20个字符:

# 自定义一个字段
    def descript_str(self, obj):
        # 对字段进行切片,取前20个字符
        return obj.descript[:20]
    # 设置自定义字段名字
    descript_str.short_description = '简介'

建立了继承于admin.ModelAdmin的类后必须将类注册到管理网站,上面的代码通过admin.site.register(models.book, bookadmin)将book数据模型注册,将models.book和bookadmin关联起来,以后在列表页面、修改页面上管理book中的数据采用的是bookadmin类中定义的形式。

下面是admin中的第二段代码,定义了管理publishing数据的页面形式。

class publishingadmin(admin.ModelAdmin):
    list_display = ('name','address')
    list_editable = ('address',)
    list_per_page = 10
admin.site.register(models.publishing,publishingadmin)

下面是第三段代码,定义author数据的页面功能与样式:

from  django.utils.safestring import mark_safe
class authoradmin(admin.ModelAdmin):
    # 自定义字段,使图片带有HTML格式并显示
    # mark_safe函数避免格式字符被转义
    def header_data(self,obj):
        return mark_safe(u'<img src="/media/%s" width="50px" height="30px"/>' % obj.header)
    # 定义字段名称
    header_data.short_description = '简介'
    list_display = ('name','email','birthday','header_data')
    list_per_page = 10
admin.site.register(models.author,authoradmin)

说明:

代码通过函数形式自定义了一个字段header_data,第一个参数self代表类本身,第二个参数obj代表关联的数据模型对象,这里指的是author数据模型的实例对象。这个自定义字段函数通过return返回一个img标签作为字段值。

通过list_display = ('name','email','birthday','header_data')把自定义字段放在其中,值是img标签。

批处理功能

在对数据库表的数据进行修改时,采取的操作方式是选中记录,然后到修改页面中修改相应的字段。如果要同时修改多条数据,这样的操作是重复的。Django Admin提供了自定义函数actions,这样就可以实现对数据的批量修改。

下面把book表中已选中记录的出版社改为“新生活出版社”,在bookadmin类中加入以下代码:

# 定义批处理方法
def change_publishing(self,request,queryset):
    publishing_obj=models.publishing.objects.get(name='新生活出版社')
    rows=queryset.update(publishing=publishing_obj)
    self.message_user(request,'%s 条记录被修改成“新生活出版社”' % rows)
change_publishing.short_description='选中记录的出版社改为“新生活出版社”'
# 把方法名加到actions中
actions = ['change_publishing']

说明:

定义批处理方法采用函数定义的方式。这个函数有三个参数:self指的是类本身,request指的是当前的HttpRequest对象,queryset指的是被选中的对象(记录)。

代码首先取得name=新生活出版社的记录对象,然后通过queryset.update把这个对象赋给publishing字段。批处理成功后通过self.message_user(request,'%s 条记录被修改成“新生活出版社”' % rows)把提示信息发送到页面上。

定义好批处理方法后要加到actions属性才能起作用。

权限管理

权限管理指的是根据系统设置的安全规则或者安全策略,使得用户可以访问而且只能访问被授权的资源。

Django Admin提供的权限管理机制能够约束用户行为,控制页面的显示内容,安全且灵活。

Django Admin采用用户、组、权限构成了权限管理机制,我们在系统中建立的每一个数据模型都会有4个默认的权限,即add、change、delete、view,权限管理就是把属于数据模型的某个权限赋予用户或组。

posted @ 2021-07-15 21:26  KKKyrie  阅读(308)  评论(0编辑  收藏  举报