django 使用内建admin后台管理系统进行数据管理
·
1、准备环境
django-admin startproject 项目名称 # 创建django项目
python manage.py startapp app名 # 创建app
setting.py 的时区语言、数据库、app配置
DEBUG = True
INSTALLED_APPS = [
'django.contrib.admin', # 后台管理系统
'django.contrib.auth', # 用户认证模块
'django.contrib.contenttypes', # 内容类型处理
'django.contrib.sessions', # 会话管理
'django.contrib.messages', # 消息管理
'django.contrib.staticfiles', # 静态文件管理
'General' # 创建的app
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': 3306
}
}
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_TZ = True
DEBUG = True才可以访问admin
urls.py里面可以修改站点访问路径,默认是admin,那么python manage.py runserver 127.0.0.1:8080就是访问http://127.0.0.1:8080/admin/
urlpatterns = [
path('admin/', admin.site.urls), # 可修改url
]
2、新建APP、修改models.py
这是一个示例用的models.py
from typing import Any
from django.db import models
import datetime
# Create your models here.
# models.Manager模型管理类
class QuestionManager(models.Manager):
def get(self, *args: Any, **kwargs: Any) -> Any: # 重写get方法
try:
return super().get(*args, **kwargs)
except:
return None
def get_tags(self, name) -> models.QuerySet: # 自定义方法
question = super.get(name=name)
if question:
return question.tag.all()
else:
return []
class Question(models.Model):
id = models.AutoField(primary_key=True)
no = models.IntegerField(null=False,unique=True,verbose_name='题号')
name = models.CharField('题目',blank=False,max_length=1024)
href = models.URLField('链接')
class_name = models.CharField('类名',blank=False,unique=True,max_length=128)
update_time = models.DateTimeField('修改时间',auto_now=True)
objects = models.Manager() # 使objects不被QuestionManager覆盖
question_manager = QuestionManager() # 添加自定义模型 它会覆盖objects,如果不行被覆盖,就加上objects = models.Manager()
class Meta:
db_table = 'question'
verbose_name = '问题'
verbose_name_plural = '问题'
def update(cls,*args,**kwargs):
super().update(*args,**kwargs,updated_at=datetime.dattime.now())
@property
def tags(self): # 将方法转换为属性
res = []
for t in self.tag.all(): # 通过外键反向查找
res.append(t.name)
return ' '.join(res)
def __str__(self) -> str:
return self.name
tag_choices = (
('排序','排序'),
('回溯法','回溯法'),
('动态规划','动态规划'),
('二叉树','二叉树'),
)
class Tag(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField('标签名',choices=tag_choices,blank=False,max_length=128)
question = models.ForeignKey(Question,related_name='tag',null=True,on_delete=models.SET_NULL,verbose_name='问题')
class Meta:
db_table = 'tag'
verbose_name = '标签'
verbose_name_plural = '标签'
unique_together = ['name', 'question']
class Test(models.Model):
id = models.AutoField(primary_key=True)
update_time = models.DateTimeField(auto_now=True)
result = models.IntegerField(choices=((0,'失败'),(1,'成功')),default=1)
question = models.ForeignKey(Question, related_name='test',null=True,on_delete=models.SET_NULL,verbose_name='问题')
class Meta:
db_table = 'test'
verbose_name = '测试'
verbose_name_plural = '测试'
2.1、models.Manager
models.Manager:可以自定义模型管理对象,重写all、filter、get,也可以自定义方法
上面的例子中QuestionManager是自定义模型类,在Question中使用
Manager会自动覆盖objects,如果不想objects被覆盖,就需要加上objects = models.Manager()
下面是验证效果
try:
question = Question.objects.get(name='123') # 报错
print("Question.objects.get(name='123')",question)
except:
print("Question.objects.get(name='123') raise error")
try:
question = Question.question_manager.get(name='123') # 返回None
print("Question.question_manager.get(name='123')",question)
except:
print("Question.question_manager.get(name='123') raise error")
2.2、@property
@property:将方法转换为属性
使用方法:
question = Question.objects.get(name='aaa')
print(question.tags)
2.3、verbose_name
verbose_name是admin中对应的名称
2.4、执行迁移
python manage.py makemigrations
python manage.py migrate
3、将models加入admin
在app的下面有一个admin.py文件
from django.contrib import admin
# Register your models here.
from django.contrib import admin
from General.models import Question,Tag,Test
# 可以修改admin的title及header
admin.site.site_header = 'XX平台'
admin.site.site_title = 'XX系统'
class QuestionAdmin(admin.ModelAdmin):
# tags是@property装饰的方法,数据库不包含这个字段,只用来展示数据
# 我么也可以自定义方法来展示数据,如get_tags
list_display = ('no', 'name', 'tags', 'href','update_time', 'get_question_tags') # 列表中展示
list_editable = ('href',) # 列表中编辑
list_filter = ('name',) # 列表中过滤
list_display_links = ('name',) # 在字段上创建链接,点进去进入编辑页面
list_max_show_all = 10 # 列表中最多展示数据
list_per_page = 10 # 用于分页 每页最多展示数据
ordering = ['no'] # 排序
fields = (('no', 'name'), ('class_name', 'href')) # 编辑页面的数据展示
# 数据库中不存在,仅用于admin中展示数据
def get_question_tags(self,obj):
res = [t.name for t in obj.tag.all()]
return ', '.join(res)
get_question_tags.short_description = '标签' # 定义字段名
# 另外一种写法 使用装饰器 效果相同
# @admin.display(description='标签')
# def get_question_tags(self,obj):
# res = [t.name for t in obj.tag.all()]
# return ', '.join(res)
admin.site.register(Question, QuestionAdmin)
admin.site.register(Tag)
admin.site.register(Test)
如果有只想在admin中展示,表中不存在的数据,可以参考get_question_tags的写法
效果如下:


tag和test没有admin.ModelAdmin注入,效果如下

有一点要注意,外键是不能直接展示在list_display中的,如果想要展示需要类似get_question_tags的处理
更多推荐
所有评论(0)