• 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自带登录注销公功能
  • 相关阅读:
    poj 3693 Maximum repetition substring 重复次数最多的连续子串
    hdu 3518 Boring counting 后缀数组 height分组
    Codeforces 920G List Of Integers 二分 + 容斥
    Codeforces 920E Connected Components? 补图连通块个数
    Codeforces 920D Tanks
    LeetCode Weekly Contest 70 A B C D
    Educational Codeforces Round 37 A B C D E F
    检查站点SSL证书配置是否正确
    nginx rewrite之后post参数丢失问题
    Linux中如何避免buffers/cached占用过多内存
  • 原文地址:https://www.cnblogs.com/xiaonq/p/8012071.html
Copyright © 2020-2023  润新知