Django Admin

Posted jiaxinzhu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django Admin相关的知识,希望对你有一定的参考价值。

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

 

以上是关于Django Admin的主要内容,如果未能解决你的问题,请参考以下文章

django1.6 admin不能登录

如何在 Django Summernote 中显示编程片段的代码块?

Django 1.6 到 1.11 Admin.py 迁移

Django admin后台操作

怎么使用django里面admin的部分内容

Django内置 Admin