Django提供了一个可以运行后台数据管理的站点admin----Admin后台管理系统,该系统可以从模型中读取元数据,并提供以模型为中心的界面。admin站点可用于管理网站的用户、组、模型各种数据。让管理员可以便携的管理、发布、维护网站的内容。
要使用admin站点,需要完成:注册应用、注册上下文、注册中间件、配置URL、迁移数据库和创建超级用户。
#创建一个新的项目
django-admin startproject demo
#第一种:在数据库里新建一个新的数据库demo_admin
#第二种:win+r在命令提示符里创建数据库demo_admin
create database demo_admin
#查看是否创建成功
show databases;
#在settings.py中配置数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'demo_admin',
'HOST':'localhost',
'PORT': 3306,
'USER':'root',
'PASSWORD':'myy040715'
}
}
#生成迁移文件
python manage.py makemigrations
#执行迁移文件
python manage.py migrate
以下都是在创建项目的时候已经配置好了 ,做一下解析。
注册应用:在settings.py项目配置文件的INSTALLED_APPS变量中注册admin应用以及相关的支持应用
注册上下文:在TEMPLATES模板配置变量的OPTIONS参数包含auth和messages上下文处理器
注册中间件:在模板配置变量MIDDLEWARE中包含AuthenticationMiddleware中间件和Message-Middleware中间件
配置URL:在urls.py文件中添加Admin站点得URL配置
在浏览器中运行:http://127.0.0.1:8000/admin
第一种:
python manage.py createsuperuser
第二种:可以通过用户模型创建用户
python manage.py shell
#导入用户User模型
from django.contrib.auth.models import User
user=User.objects.create(username='demo1')
user.set_password('123456') #用set_password方法存的是哈希值,否则是明文
user.is_superuser=True
user.save()
在数据库auth-user可以查看创建得用户
然后用创建的用户登录进网站
登录页面后更改中文:
第一种:
第二种:
添加用户(add)需要权限访问该网站:
查看所有用户
删除用户:
修改用户:
创建一个应用:
python manage.py startapp app
在app/admin.py中自定义标题代替Admin的默认标题
from django.contrib import admin
# Register your models here.
admin.site.site_title='在线图书后台管理系统'
admin.site.site_header='在线管理网站'
注册模型方式:一种使用修饰器@admin.register()注册模型;另一种是使用admin.site.register()注册模型
定义模型(models.py):
from django.db import models
# Create your models here.
class bookinfo(models.Model):
name=models.CharField(max_length=20,verbose_name='书籍名')
author = models.CharField(max_length=20,verbose_name='书籍作者')
price = models.IntegerField(verbose_name='书籍定价')
class Meta:
verbose_name='书籍信息'
verbose_name_plural='书籍信息'
#生成迁移文件
python manage.py makemigrations
#执行迁移文件
python manage.py migrate
注册模型:
from .models import bookinfo
#第一种
admin.site.register(bookinfo)
#第二种:
@admin.register(bookinfo)
class BookAdmin(admin.ModelAdmin):
pass
可观察到站点管理页面中新增了TESTADMIN,其中“书籍信息”为定义TESTADMIN模型时使用verbose_name_plural属性定义的书籍名
在应用app的_init_.py文件中添加如下配置
default_app_config = 'app.apps.AppConfig'
在应用app中apps.py文件的TestadminConfig类中使用verbose_name设置应用的名称
from django.apps import AppConfig
class AppConfig(AppConfig):
name = 'app'
verbose_name='图书管理系统'
admin站点中查看:
删除数据:
Django提供了一些选项来控制列表页的显示字段、搜索字段、过滤器等,这些选项在应用的admin.py文件的模型管理类中使用。
list_display选项用于控制页面展示的字段,该字段的值为元组或列表类型。使用list_display属性在页面中显示书籍的id和书籍名称、作者和定价
#app/admin.py
@admin.register(bookinfo)
class BookAdmin(admin.ModelAdmin):
#list_display=你需要展示的字段应该写在这里,此处数据库中的字段
list_display=('id','name','author','price')
list_display_links选项用于设置需要在页面中以链接形式展现字段,链接字段必须是模型中的字段。
list_display_links=('id','name')
list_filter用于开启列表页过滤器,该选项可以接收模型中的字段作为过滤条件,也可以接受自定义过滤器。
list_filter=('name','price')
Search_fieds选项用于开启列表页搜索框,该选项可以接受模型中的字段作为条件,对数据库进行模糊查询。
search_fields=('author','name')
ordering选项用于设置列表页的一个排序条件
ordering =('price',)
使用list_per_page选项可以设置每页显示得数据量,默认每页显示100条数据,设置列表每页显示1条数据
list_per_page=1
list_editable选项用于设置可编辑得字段,字段若被指定为编辑字段,页面上可直接编辑该字段,设置书籍定价为可编辑字段
list_editable = ('price',)
readonly选项用于设置不可编辑得字段,字段若被指定为只读字段,则不可以编辑该字段。
readonly_fields=('name',)
actions选项用于设定管理员动作。列表默认提供“删除选项”动作,管理员选定书籍后选择“删除所选”动作,再单击“执行”按钮,选定的商品会被删除。
actions选项也支持自定义管理员动作。自定义管理员动作的本质是在管理类中新增一个方法,并将该方法添加到actions选项中。
from django.contrib import admin
# Register your models here.
admin.site.site_title='在线图书后台管理系统'
admin.site.site_header='在线管理网站'
from .models import bookinfo
# admin.site.register(bookinfo)
from django.http import HttpResponse
from django.utils.encoding import escape_uri_path
from openpyxl import Workbook
#需要先在终端执行pip install openpyxl命令下载此模块
@admin.register(bookinfo)
class BookAdmin(admin.ModelAdmin):
#设置action动作
def download_excel(self,request,queryset):
file_name = '书籍信息.xlsx'
meta = self.model._meta #用于定义文件名,格式为:app名.模型类名
#模型所有字段名
field_names = [field.name for field in meta.fields]
#定义响应内容类型
response = HttpResponse(content_type='application/msexcel')
#定义响应数据格式
# response['Content-Disposition'] = f'attachment;filename = {meta}.xlsx'
response['Content-Disposition'] = f'attachment;filename="{escape_uri_path(file_name)}"'
wb = Workbook() #新建workbook
ws = wb.active #使用当前活动的Sheet表
ws.append(['ID','书籍名称','作者','书籍定价'])
for obj in queryset: #遍历选择的对象列表
for field in field_names:
#将模型属性值的文版格式组成列表
data = [getattr(obj, field) for field in field_names]
ws.append(data) #将数据存入响应内容
wb.save(response)
return response
download_excel.short_description = "下载信息"
list_display = ('id', 'name', 'author', 'price')
list_display_links = ('id', 'name')
list_filter = ('name',)
search_fields = ('author', 'name')
ordering = ('price',)
list_per_page = 1
list_editable = ('price',)
readonly_fields = ('name',)
actions = (download_excel,)
actions_on_top = True
actions_on_bottom = True
点击执行按钮
Admin的原生模板提供了良好的后台页面,但这 并不能满足所有的业务需求,此时开发人员可以 重写Admin原生模板以拓展模板功能。
本节中选用Simple UI工具来美化Admin站点,simpleui是django admin的一个主题,主要是为了美化和简化django内置的后台管理界面。是一个基于element-uitvue开发,重写和优化90%以上的页面。与 suit是同类产品。是一个更符合国人审美和使用习惯的一一个主题
下面以在线图书管理系统为例,使用Simple UI对站点进行美化,具体步骤如下。
第一步:安装Simple UI
pip install django-simpleui
第二步:验证
pip list
第三步:修改默认后台模板为simpleui
在settings.py文件的INSTALLED_APP中添加"simpleui"。
第四步:克隆静态文件
在项目文件夹下创建静态文件static文件,然后再settings.py中修改配置
DEBUG关闭后需要解决静态资源无法访问的情况,再settings.py中添加配置
使用python manage.py collectstatic进行静态文件克隆,会自动生成admin文件
注意:如果出现如下代码,输入yes即可。若出现加深字段显示代码,是路径配置出现问题,可直接在系统对应路径找到该static文件,然后将static内admin文件夹直接复制到“demo/static"文件夹下。
第五步:启动项目
将settings.py文件中的DEBUG重新改为DEBUG=True
第一步:在Django项目目录下 创建templates目录 与static目录,并在 templates目录下创 建admin目录。
第二步:base_site.html模板 存储在 “D:\学习\Virtualenv\test\Lib\site-packages\django\contrib\admin\templates\admin”中, 按照该路径找到 base_site.html模板, 将base_site.html模 板拷贝到templates/ admin目录下。
第三步:在settings.py文件中 配置templates目录 与static目录
第四步:将准备好的网站logo 图片添加到static目录 下。
重写base_site.html 模板。
{% extends "admin/base.html" %}
{% load staticfiles %}
{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}
{% endblock %}
{% block branding %}
{% endblock %}
{% block nav-global %}{% endblock %}
在浏览器上运行
User模型用于管理用户数据,模型包含的字段如下。
在数据库中,User模型对应的数据表为auth_user
调用create()方法创建user对象
from django.contrib.auth.models import User
user=User.objects.create(username='testuser')
user.set_password('123456')
user.save()
注意,为用户设置密码应调用set passwordO方法,该方法将明文密码转换成的哈希值存入password 字段。User 模型提供了创建普通用户create _user(和超级用户的方法create_superuser()
user=User.objects.create_superuser('admin3','[email protected]','123456')
use.save()
user=User.objects.create_user('test2','[email protected]','123456')
use.save()
以上代码分别使用create_user和create_superuser()方法创建了用户admin3和test2,并使用save()方法将用户信息保存到数据库中
可通过模型对象修改用户相关属性
user=User.objects.get(username='testuser')
user.email='[email protected]'
user.save()
user.email
调用模型对象的delete()方法可删除用户
user=User.objects.get(username='test')
user.delete()
authenticate()方法将用户名和密码作为参数来验证用户。如果用户名和密码正确,方 法返回关联用户名的User模型对象;未通过验证时,返回None。
from django.contrib.auth import authenticate
user=authenticate(username='testuser',password='123456')
print(user)
user=authenticate(username='testuser',password='456')
print(user)
user=authenticate(username='test2',password='123456')
print(user)
Permission模型用于管理权限数据,模型包含的字段如下。
在数据库中,Permission模型对应的数据表为auth_permission
User模型与Permission模型之间是多对多关系,可以从关系的两端为用户设置权限。
通过User对象设置权限.
from django.contrib.auth.models import Permission
>>> admins=Permission.objects.filter(codename__endswith='permission') #获取权限
>>> user=User.objects.get(username='testuser')
>>> user.user_permissions.set(admins) #设置权限
>>> for p in user.user_permissions.all(): #查看权限
... print(p.codename,p.name)
创建新的权限,并授权给用户
from app.models import bookinfo
from django.contrib.contenttypes.models import ContentType
content_type_id=ContentType.objects.get_for_model(bookinfo)
print(content_type_id)
p=Permission.objects.create(codename='can_analyse_person',
name='能分析person数据',content_type=content_type_id)
user.user_permissions.add(p)
通过Permission模型为用户授权
from django.contrib.auth.models import Permission
from django.contrib.auth.models import User #获取权限对象
p=Permission.objects.get(codename='view_permission') #为权限添加关联用户
user=User.objects.get(username='testuser')
p.user_set.add(user)
p.user_set.all()
也可通过将用户加入组的方式来为用户授权
from django.contrib.auth.models import Group
g=Group.objects.get(id=1)
g.user_set.add(user) #将用户加入组
Django在django.contrib.auth.views.py中定义了几个用于登录、注销和密码管理的认证视图 类。
要使用内置的认证视图,首先需要在配置文件中添加下面的URL配置。
from django.contrib import admin
from django.urls import path,include
from .import views
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/',include('django.contrib.auth.urls')),#导入内置认证视图URL配置
path('accounts/profile/',views.login_ok),#映射自定义视图
]
Django在默认视图中会使用项目配置文件settings.py中设置 的3个URL。
在django.contrib.auth.urls中包含了访问内置认证视图的url配置,文件路径:D:\学习\Virtualenv\test\Lib\site-packages\django\contrib\auth\urls.py
在URL配置中没有为视图指定模板,所以这些内置认证视图均使用默认的模板文件。每个内置认证视图都有默认的模板文件名,例如,登录视图LoginView的默认模板文件名称为registration/login.html.本项目中,路径位于“testusertemplateslregistrationlogin.html"
注意: Django 只指定了登录视图的默认模板文件名,但没有定义该文件。其他的视图都有可以使用的默认模板文件。通常在应用的“templateslregistration"文件夹中创建自定义模板文件。
登录视图用于处理用户登录操作,该视图默认的URL模式名称为 login。
在模板中可用{% url 'login' %}获取登录视图URL。
在采用GET方法访问登录视图时,视图显示默认登录表单。
当用户输入用户名和密码后再提交表单时,登录视图使用用户数据 表auth_user中的数据验证用户名和密码是否正确。
用户通过验证时,视图调用login()方法,将用户的User对象写入 Session对象,同时会在auth_user表中记录登录时间。
用户未通过验证时,重新显示登录页面,并在页面中显示错误提示 信息。
登录视图会向模板传递下列变量。
基于Django内置视图实现网站登录功能
D:\学习\python web开发\课程\admin\demo\templates\registration\login.html
App应用:使用Django内置登录视图
{% if form.errors %}
用户名或密码有错,请重新登录!
{% endif %}
定义视图函数,实现用户登录成功后重定向URL“/accounts/profile/”映像的视图
from django.shortcuts import render
def login_ok(request):
return render (request,'registration/login_ok.html')
创建模板文件login_ok.html
{% if user.is_authenticated %}
登录成功,欢迎:{{ user.username }},登录时间:{{ user.last_login }}
{% if perms.test %}
你拥有访问应用test的下列权限:
{% for a in user.user_permissions.all %}
- {{a.name}},{{a.codename}}
{% endfor %}
{% else %}
你还没有访问应用的任何权限!
{% endif %}
{% else %}
你还未登录,请登录
{% endif %}
使用django内置认证视图,url配置
from django.contrib import admin
from django.urls import path,include
from .import views
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/',include('django.contrib.auth.urls')),#导入内置认证视图URL配置
path('accounts/profile/',views.login_ok),#映射自定义视图
]
若用户名和密码都正确,登录成功,页面跳转到登录成功界面(login_ok.html)
注销登录视图用于处理用户注销登录操作,注销登录会删除Session中的用户信息。
单击"注销登录?"链接,可执行注销操作,并跳转到默认响应页面。
会使用Admin默认的注销登陆模板 ,使用自定义的注销登录模板。
配置URL
from django.contrib.auth import views as auth_views
path('login/', auth_views.LoginView.as_view(template_name='registration/login.html')),
path('logout/',auth_views.LogoutView.as_view(template_name='registration/logged_out2.html'),name='logout2'),
修改前面登录成功的模板,此文件加在login_ok.html文件下
创建模板文件logged_out2.html
Title
成功注销登录,欢迎再次登录
在开发练习中,读者可使用之前介绍的使用css 的方式对本节登录注销等各个页面进行美化,注销成功后,可点击再次登录或单击浏览器工具栏中的后退按钮,返回前面的登录成功页面。因为用户已注销登录,所以页面中不会显示用户名和权限等信息.
密码修改视图用于修改用户密码,视图的默认URL模式名称为password_change。
密码修改视图会向模板传递一个form变量,用于引用密码修改表单。
默认情况下,密码修改视图使用Admin站点的密码修改模板。
修改前面的登录成功视图模板文件login_ok.html,添加修改密码链接.
点击"修改密码"
密码重置视图用于在用户忘记密码时申请重置密码,视 图默认的URL模式名称为password_reset。
密码重置视图的默认模板文件为registration/password_reset_form.html,
同时,视图还使用下面的两个默认模板。
密码重置邮件内容模板:registration/password_reset_email.html, 可用视图的email_template_name属性设置。
密码重置邮件主题模板:registration/password_reset_subject.txt, 可用视图的subject_template_name属性设置。
login.html
urls.py
path('reset///', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
在密码重置页面输入一个E-mail地址后,Django向该地址发送一封密码重置邮件。只有当输入的E-mail地址在auth user 表中存在时,才会向该地址发送密码重置邮件。密码重置邮件包含了一个一次性的链接,用户单击该链接可进入密码重置确认页面设置新的密码。
在自定义视图中,可调用django.contrib.auth模块提 供的下列方法进行身份认证。
authenticate():以用户名和密码为参数验证用户。用户名 和密码均正确时,返回该用户的User对象,否则返回None。
login():执行登录注册。将用户的User对象保存到Session中。 用户登录之前保存在Session中的数据,在登录后仍然会保 留。
logout():注销登录,删除Session中的会话数据。
第一步:定义视图函数(app.views.py)
from django.contrib.auth import authenticate, login,logout
from django.shortcuts import render,redirect
from django.urls import reverse
from django.http import HttpResponse
def login_diy(request):
uid = ''
news = ''
if request.method == 'POST':
uid = request.POST['username']
pwd = request.POST['password']
user = authenticate(username=uid, password=pwd)
if user is not None:
login(request, user)
return redirect('log_success')
else:
news = "用户名或密码错误!"
context = {'username': uid, 'news': news}
return render(request, 'login_diy.html', context)
登录视图使用模板login.diy.html,在模板中用表单接受用户和密码
{{news}}
定义登录成功处理视图。视图在页面中显示成功信息,用户名和链接
def log_success(request):
news='登录成功,欢迎:%s,注销登录?'%\
(request.user.username,reverse('logoutdiy'))
return HttpResponse(news)
def logout_diy(request):
logout(request) #注销登录
news='登录注销成功,欢迎再次登录?'%reverse('logindiy')
return HttpResponse(news)
配置URL:
path('logindiy/', views.login_diy, name='logindiy'),
path('log_success/', views.log_success, name='log_success'),
path('logoutdiy/', views.logout_diy, name='logoutdiy'),
可以使用自定义方式或者登录装饰器来限制页面登录 访问。
通常,可通过request.user.is_authenticated的值来判断用户是否已经登录,其值为True表示用户已经登录,否则未 登录。下面的视图在用户未登录时跳转到登录页面,用户成功登录后,再返回登录前视图。
from django.conf import settings
def testlogin(request):
if not request.user.is_authenticated:
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
else:
news='欢迎:%s,你已经登录,可以访问本页面,注销登录?'%\
(request.user.username,reverse('logoutdiy'))
return HttpResponse(news)
settings.LOGIN_URL是在项目配置文件中定义的默认登录URL
LOGIN_URL='/accounts/login/'
配置URL访问testlogin视图
path('testlog/', views.testlogin,name='testlogin'),
登录装饰器login_required用于限制页面只能在用户登录后访问。
from django.contrib.auth.decorators import login_required
@login_required
def testlogin2(request):
news='欢迎:%s,你已经登录,可以访问本页面,注销登录?'%\
(request.user.username,reverse('logoutdiy'))
return HttpResponse(news)
配置url:
path('testlog2/', views.testlogin2,name='testlogin2'),
(1).装饰器permission_required可用于限制访问页面必须具备特定权限,定义视图views.py
from django.contrib.auth.decorators import login_required,permission_required
@login_required
@permission_required('app.can_addperson')
def testlogin3(request):
news='欢迎:%s,你已经登录,可以访问本页面,注销登录?'%\
(request.user.username,reverse('logoutdiy'))
return HttpResponse(news)
配置urls.py
path('testlog3/', views.testlogin3,name='testlogin3'),
根据代码,用户需要登录且具有can_addperson
权限才能访问testlogin3
视图函数。如果用户登录成功且具有该权限,则会返回一个欢迎消息。但是,从代码中无法判断登录是否成功。您可以在登录成功后,使用HttpResponseRedirect
将页面重定向到相应的页面,或者在前端页面上显示提示信息,以提高用户体验。
(2).user_ passes_ test 装饰器
在生活中会经常会遇到QQ用户或博客等可以设置将朋友列表中莫用户拉入黑名单,进入黑名单的用户不能访问空间或博客。在Django中可以通过一些装 饰器来实现此功能。
装饰器userpasses_test允许使用自定义函数来检测已登录用户是否可以访问页面,例如,使用之前的创建用户的方式创建一个 root用户,在项目配置文件sttingspy中设置黑名单列表,将新创建的test2用户设置为黑名单用户。
LOGIN_BLACKLIST=['test2']
定义视图函数check_in_blacklist,功能是检测用户未登录或属于黑名单用户
from django.contrib.auth.decorators import user_passes_test
def check_in_blacklist(user):#检测用户是否在黑名单中
return not user.username in settings.LOGIN_BLACKLIST
@user_passes_test(check_in_blacklist)
def testlogin4(request):
news='欢迎:%s,你已经登录,可以访问本页面,注销登录?'%\
(request.user.username,reverse('logoutdiy'))
return HttpResponse(news)
配置URL
path('testlog4/', views.testlogin4,name='testlogin4'),
@user_ passes test(check _in _blacklist)"检测出root属于黑名单用户,所以使页面重定向到登录页面。不能进行跳转。此时继续尝试在settings.py中将黑名单中的root删除。
刷新页面,再次输入root用户和密码后点击登录,页面成功跳转到htp://27.0.0.1:8000/testuser/testltg3g/页面,此时@user passes test(check in_ blacklist)"检测出root不属于黑名单用户,所以能够没有限制该用户访问页面。