06: Django Admin

时间:2023-03-09 13:43:46
06: Django Admin

目录:Django其他篇

01:Django基础篇

02:Django进阶篇

03:Django数据库操作--->Model

04: Form 验证用户数据 & 生成html

05:ModelForm 数据验证 & 生成html & 数据库操作

06: Django Admin

07: Django 学习补充

目录:

1.1 Django Admin基本使用返回顶部

  1、Django Admin 基本使用演示

from django.db import models

class User(models.Model):
username = models.CharField(max_length=32,verbose_name='用户名')
pwd = models.CharField(max_length=64,verbose_name='密码')
ctime = models.DateTimeField(auto_now=True)
ut = models.ForeignKey(to='UserType',to_field='id',verbose_name='用户类型')
m2m = models.ManyToManyField("Group")
def __str__(self):
return self.username
class Meta:
verbose_name_plural = '用户表' class UserType(models.Model):
user_type_name = models.CharField(max_length=32)
def __str__(self):
return self.user_type_name class Group(models.Model):
group_name = models.CharField(max_length=32)
def __str__(self):
return self.group_name

models.py创建表结构

from django.contrib import admin
from app01 import models class UserAdmin(admin.ModelAdmin):
list_display = ('username','pwd','ut','ctime',) admin.site.register(models.User,UserAdmin)
admin.site.register(models.UserType)
admin.site.register(models.Group)

admin.py中注册表

   2、简单说明

      1. 在admin.py中可以使用 list_display 指定显示那些字段,但是不能显示多对多字段

      2. 在创建时一对多显示为单选下拉菜单,多对多显示为多选下拉菜单

1.2 admin.py中用来自定制常用参数返回顶部

  1、UserAdmin自定制常用参数

from django.contrib import admin
from app01 import models class UserAdmin(admin.ModelAdmin):
list_display = ('username','pwd','ut','ctime',)
list_filter = ('source','consultant','date') #过滤字段
search_fields = ('qq','name') #搜索匹配字段
raw_id_fields = ('consult_course',)
filter_horizontal = ('tags',) #多对多字段显示
list_per_page = 1 #每页显示几条数据
list_editable = ('source',) #可编辑的字段
readonly_fields = ('qq',) #只读字段
exclude = ('name',) # 添加和修改时那些界面不显示
date_hierarchy = 'ctime' # 详细时间分层筛选 
actions = ['test_action',] #之定义的action函数
def test_action(self, request, arg2): # 自定义action函数
'''
:param self: crm.CustomerAdmin类本身
:param request: 客户端request请求
:param arg2: 前端选中的数据实例
''' admin.site.register(models.User,UserAdmin) admin.site.site_header = '重写DjangoAdmin管理系统' # 修改系统显示名称
admin.site.site_title = '我的后台管理界面' # 修改页面 title

UserAdmin自定制常用参数

  2、将页面显示成中文(在settings.py中修改)

      LANGUAGE_CODE = 'zh-hans'
      TIME_ZONE = 'Asia/Shanghai'

  3、修改页面项目显示名称 (admin.py中修改)

      admin.site.site_header = '重写DjangoAdmin管理系统'                # 修改系统显示名称
      admin.site.site_title = '我的后台管理界面'                                    # 修改页面 title

1.3 定制:增加、修改、删除前执行函数返回顶部

# admin.py
from django.contrib import admin
from app01 import models class UserAdmin(admin.ModelAdmin):
list_display = ('username','pwd','ut','ctime',) # 通过change参数,可以判断是修改还是新增,同时做相应的操作
def save_model(self, request, obj, form, change):
if change: # 更改的时候
print('修改会执行这里')
else: # 新增的时候
print('新增会执行这里')
super(UserAdmin, self).save_model(request, obj, form, change) def delete_model(self, request, obj):
print('删除时会执行这里')
obj.delete() admin.site.register(models.User,UserAdmin)

定制:增加、修改、删除前执行函数

1.4 Django admin的一些有用定制返回顶部

  1、字段级别的权限

      作用:不同权限的可以编辑不同的内容,可以通过get_readonly_fileds()来添加字段只读权限。

class EntryAdmin(admin.ModelAdmin):
list_display=(...)
search_fields=(...)
def get_readonly_fields(self,request,obj=None):
if not request.user.is_superuser and not request.user.can_edit:
return [f.name for f in self.model._meta.fields]
return self.readonly_fields

字段级别的权限

  2、不同的用户显示不同的数据行,重写列表页面返回的查询集

      作用:ModelAdmin提供了一个钩子程序 —— 它有一个名为queryset() 的方法,该方法可以确定任何列表页面返回的默认查询集。

class MyModelAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(MyModelAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)

不同的用户显示不同的数据行,重写列表页面返回的查询集

1.5 重写Django Admin用户认证返回顶部

  1、说明

      1. Django Admin中通过python manage.py createsuperuser创建的用户默认存储在自己的User表中

      2. 很多时候我们想要借助这个用户认证,但是Django中自带的User表我们是无法添加其他字段的

      3. 所以为了更方便的使用Django admin的认证功能,可以使用我们自己的UserProfile表代替Django Admin的User表

  2、重写步骤

      1、models.py中定义表结构

      2、admin.py中注册UserProfile表,并定制UserProfileAdmin
          注:如果只定义表结构而没有定制UserProfileAdmin,在页面创建的用户密码为明文,无法登陆admin后台

      3、一定要记得到settings.py指定使用我们自定义的UserProfile表做登录验证

      4、执行创建表命令
          python manage.py makemigrations
          python manage.py migrate
          python manage.py createsuperuser

      5、此时就可以登陆admin后台创建用户,修改面等操作了

from django.db import models
from django.utils.translation import ugettext_lazy as _ #国际化
from django.utils.safestring import mark_safe
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser,PermissionsMixin
) #1. 创建用户时调用这个类
class UserProfileManager(BaseUserManager): #这个方法用来创建普通用户
def create_user(self, email, name, password=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model( #验证email
email=self.normalize_email(email),
name=name,
)
user.set_password(password) #让密码更安全,设置密码,给密码加盐
self.is_active = True #指定创建用户默认是active
user.save(using=self._db) #保存创建信息
return user
def create_superuser(self, email, name, password): #这个方法用来创建超级用户
user = self.create_user(
email,
password=password,
name=name,
)
user.is_active = True
user.is_admin = True
user.save(using=self._db)
return user #2 创建UserProfile表替代Django admin中的user表做用户登录
class UserProfile(AbstractBaseUser,PermissionsMixin):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
null=True
)
password = models.CharField(_('password'),
max_length=128,help_text=mark_safe('''<a href='password/'>修改密码</a>'''))
name = models.CharField(max_length=32)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
#roles = models.ManyToManyField("Role",blank=True) objects = UserProfileManager() #创建用户时会调用这里类 USERNAME_FIELD = 'email' #自己指定那个字段作为用户名
REQUIRED_FIELDS = ['name'] #那些字段是必须的 # 下面这些是默认方法不必修改它
def get_full_name(self): # The user is identified by their email address
return self.email
def get_short_name(self): # The user is identified by their email address
return self.email
def __str__(self): # __unicode__ on Python 2
return self.email
def has_perm(self, perm, obj=None): #对用户授权(如果注释掉用户登录后没任何表权限)
return True
def has_module_perms(self, app_label): #对用户授权(如果注释掉用户登录后没任何表权限)
return True
@property
def is_staff(self):
#return self.is_admin #这个必须是指定admin才能登陆Django admin后台
return self.is_active #这个只要用户时is_active的即可登陆Django admin后台

models.py

#解决我们改写的Django admin 中user表验证时密码明文问题
from django.contrib import admin
from django import forms
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from app01 import models #1、不必改什么(创建用户时调用这个类)
class UserCreationForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput) class Meta:
model = models.UserProfile
fields = ('email', 'name') def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2 def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user #2、不必改什么(修改用户时调用这个类)
class UserChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField() class Meta:
model = models.UserProfile
fields = ('email', 'password', 'name', 'is_active', 'is_admin') def clean_password(self):
return self.initial["password"] #3、定制UserProfile表
class UserProfileAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserChangeForm
add_form = UserCreationForm list_display = ('email', 'name', 'is_admin',"is_staff",'password')
list_filter = ('is_admin',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal', {'fields': ('name',)}),
('Permissions', {'fields': ('is_admin',"is_active","user_permissions",'groups')}),
# ('Permissions', {'fields': ('is_admin',"roles","is_active","user_permissions",'groups')}),
)
#Permissions后的字典记得加上,is_admin,is_active否则我们无法再前端勾选,那么我们自己新建的用户无法登陆Django Admin后台 add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'name', 'password1', 'password2')}
# 'fields': ("roles",'email', 'name', 'password1', 'password2')}
),
)
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ("user_permissions",'groups',) #显示多对多的选项框 admin.site.register(models.UserProfile, UserProfileAdmin)
admin.site.unregister(Group)

admin.py

AUTH_USER_MODEL = 'app01.UserProfile'    #app名.表名

settings.py

from django.shortcuts import render,HttpResponse,redirect
from django.contrib.auth import login,authenticate,logout
from django.contrib.auth.decorators import login_required #装饰器,用来验证用户是否登录
def acc_login(request):
errors = {}
if request.method == 'POST':
_email = request.POST.get('email')
_password = request.POST.get('password')
user = authenticate(username= _email, password=_password) #通过验证会返回一个user对象
print('user',user)
if user:
login(request,user) #Django自动登录,然后创建session
next_url = request.GET.get("next","/crm/")
#未登录时直接输入url时跳转到登录界面是会加上"next"参数
return redirect(next_url)
else:
errors['error'] = "Wrong username or password!"
return render(request,'login.html',{'errors':errors}) def acc_logout(request):
logout(request)
return redirect("/account/login/")

附加:Django自带登录注销公功能