Django Admin

hoooooolyhu 2020-03-26

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自带登录注销公功能

相关推荐

inspuryhq / 0评论 2020-07-28