Python - Django Web开发(3)

Admin 管理工具

  • Django 提供了内置的 Web 管理工具,用于管理数据库中的数据。
  • 是 django.contrib 中的一部分,可以在项目的settings.py中的INSTALLED_APP中看到。
1
2
3
4
5
6
7
8
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)

使用

  1. 启动 Django 项目
  2. 访问http://127.0.0.1:8000/admin/,输入用户名和密码,进入管理页面。
1
2
3
4
5
6
# 可以通过命令 py manage.py createsuperuser 创建超级用户
Username (leave blank to use 'root'): admin
Email address: admin@admin.com
Password:
Password (again):
Superuser created successfully.
  1. 创建模型类 - app01 中使用的模型
  2. 注册模型类 - 在 app01/admin.py 中注册模型
1
2
3
4
from django.contrib import admin
from app01.models import Test

admin.site.register(Test)
  1. 再次访问http://127.0.0.1:8000/admin/,即可看到 Test 模型的数据表

复杂模型

管理页面非常强大,可以处理非常复杂的模型数据。

  1. 先在 app01/models.py 中创建一个复杂模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from django.db import models

# Create your models here.
class Test(models.Model):
name = models.CharField(max_length=20)

class Contact(models.Model):
name = models.CharField(max_length=200)
age = models.IntegerField(default=0)
email = models.EmailField()
def __unicode__(self):
return self.name

class Tag(models.Model):
contact = models.ForeignKey(Contact, on_delete=models.CASCADE,)
name = models.CharField(max_length=50)
def __unicode__(self):
return self.name
- 上述代码中有两个表,Tag以Contact为外键,一个Contact可以对应多个Tag
- IntegerField用于存储整数
  1. 在 app01/admin.py 中注册模型
1
2
3
4
5
6
7
from django.contrib import admin
from app01.models import Test,Contact,Tag

# admin.site.register(Test)
# admin.site.register(Contact)
# admin.site.register(Tag)
admin.site.register([Test, Contact, Tag])
  1. 再次访问http://127.0.0.1:8000/admin/,即可看到 Test 模型的数据表
  2. 如果未创建表结构,可以通过以下命令创建
1
2
py manage.py makemigrations [appname]
py manage.py migrate [appname]

自定义表单

  • 默认情况下,管理页面使用 Django 的表单,可以自定义表单。
  • 修改 app01/admin.py
1
2
3
4
5
6
7
8
9
from django.contrib import admin
from app01.models import Test,Contact,Tag

# Register your models here.
class ContactAdmin(admin.ModelAdmin):
fields = ('name', 'email')

admin.site.register(Contact, ContactAdmin)
admin.site.register([Test, Tag])
  • 再次访问http://127.0.0.1:8000/admin/,即可看到 Contact 的 add 页面,只有 name 和 email 字段
  • 也可以将输入栏分块,每个栏可以定义自己的格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from django.contrib import admin
from app01.models import Test,Contact,Tag

# Register your models here.
class ContactAdmin(admin.ModelAdmin):
fieldsets = (
['Main',{
'fields':('name','email'),
}],
['Advance',{
'classes': ('collapse',), # CSS格式
'fields': ('age',),
}]
)

admin.site.register(Contact, ContactAdmin)
admin.site.register([Test, Tag])

内联(Inline)显示

  • 上面的 Contact 是 Tag 的外部键,所以有外部参考的关系
  • 在默认的页面中,两者被分离,无法体现出两者的从属关系,可以通过内联显示来解决这个问题
  • 修改 app01/admin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from django.contrib import admin
from app01.models import Test,Contact,Tag

# Register your models here.
class TagInline(admin.TabularInline):
model = Tag

class ContactAdmin(admin.ModelAdmin):
inlines = [TagInline] # Inline
fieldsets = (
['Main',{
'fields':('name','email'),
}],
['Advance',{
'classes': ('collapse',),
'fields': ('age',),
}]

)

admin.site.register(Contact, ContactAdmin)
admin.site.register([Test])

列表页的显示

  • 也可以自定义该页面的显示,比如在列表中显示更多的栏目,只需要在 ContactAdmin 中增加 list_display 属性即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from django.contrib import admin
from app01.models import Test,Contact,Tag

# Register your models here.
class TagInline(admin.TabularInline):
model = Tag

class ContactAdmin(admin.ModelAdmin):
list_display = ('name','age', 'email') # list
inlines = [TagInline] # Inline
fieldsets = (
['Main',{
'fields':('name','email'),
}],
['Advance',{
'classes': ('collapse',),
'fields': ('age',),
}]

)

admin.site.register(Contact, ContactAdmin)
admin.site.register([Test])
  • 搜索功能的添加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from django.contrib import admin
from app01.models import Test,Contact,Tag

# Register your models here.
class TagInline(admin.TabularInline):
model = Tag

class ContactAdmin(admin.ModelAdmin):
list_display = ('name','age', 'email') # list
search_fields = ('name',)
inlines = [TagInline] # Inline
fieldsets = (
['Main',{
'fields':('name','email'),
}],
['Advance',{
'classes': ('collapse',),
'fields': ('age',),
}]

)

admin.site.register(Contact, ContactAdmin)
admin.site.register([Test])

注意

  • on_delete 有CASCADE/PROTECT/SET_NULL/SET_DEFAULT/SET五个可选值
    • CASCADE:级联删除
    • PROTECT:抛出 ProtectedError 异常
    • SET_NULL:将外键字段设为 null,前提是该字段允许为 null
    • SET_DEFAULT:将外键字段设为默认值
    • SET:将外键字段设为指定值,指定值由参数指定,可以是一个函数,一般情况下使用 CASCADE 就可以