zoukankan      html  css  js  c++  java
  • admin组件详解

    admin组件详解

    删除所有表:

    SELECT concat('DROP TABLE IF EXISTS ', table_name, ';')
    FROM information_schema.tables
    WHERE table_schema = 'mydb';
    

    admin 管理:

    注册:
    from django.contrib import admin
    from blog.models import Blog
      
    #Blog模型的管理器
    class BlogAdmin(admin.ModelAdmin):
        # 展示字段
        list_display=('id', 'caption', 'author', 'publish_time')
         
    #在admin中注册绑定
    admin.site.register(Blog, BlogAdmin)
    
    from django.contrib import admin
    from blog.models import Blog
      
    #Blog模型的管理器
    @admin.register(Blog)
    class BlogAdmin(admin.ModelAdmin):
        list_display=('id', 'caption', 'author', 'publish_time')
    
    界面汉化:
    settings.py中设置:
    	LANGUAGE_CODE = 'zh-hans'
    	TIME_ZONE = 'Asia/Shanghai'
    

    基本设置:

     #listdisplay设置要显示在列表中的字段(id字段是Django模型的默认主键)
        list_display = ('id', 'caption', 'author', 'publish_time')
        
        #list_per_page设置每页显示多少条记录,默认是100条
        list_per_page = 50
        
        #ordering设置默认排序字段,负号表示降序排序
        ordering = ('-publish_time',)
      
        #list_editable 设置默认可编辑字段
        list_editable = ['machine_room_id', 'temperature']
      
        #fk_fields 设置显示外键字段
         fk_fields = ('machine_room_id',)
            
     注意:
    	默认可以点击每条记录第一个字段的值可以进入编辑界面
        
     设置其他字段也可以点击链接进入编辑界面:
    	 list_display_links = ('id', 'caption')
    

    筛选器:

    @admin.register(Blog)
    class BlogAdmin(admin.ModelAdmin):
        list_display = ('id', 'caption', 'author', 'publish_time')
         
        #筛选器
        list_filter =('trouble', 'go_time', 'act_man__user_name', 'machine_room_id__machine_room_name') #过滤器
        
        search_fields =('server', 'net', 'mark') #搜索字段
        date_hierarchy = 'go_time'    # 详细时间分层筛选 
    

    报错处理:

     date_hierarchy  进行详细时间筛选的时候 可能出现报错:Database returned an invalid datetime value. Are time zone definitions for your database and pytz installed?
    
    处理方法:  
    
    命令行直接执行此命令:     [root@mysql ~]#    mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
    然后重启数据库即可。
     
    一般ManyToManyField多对多字段用过滤器;标题等文本字段用搜索框;日期时间用分层筛选。
    
    过滤器如果是外键需要遵循这样的语法:本表字段__外键表要显示的字段。如:“user__user_name”
    

    颜色设置:

    某些字段设置颜色:
        from django.db import models
    from django.contrib import admin
    from django.utils.html import format_html
     
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
     
        def colored_name(self):
            return format_html(
                '<span style="color: #{};">{} {}</span>',
                self.color_code,
                self.first_name,
                self.last_name,
            )
     
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name', 'colored_name')
        
     注意:
    	代码,是写在models里,而不是admin中的ModelAdmin里
    

    调整标题:

    class MyAdminSite(admin.AdminSite):
        site_header = '好医生运维资源管理系统'  # 此处设置页面显示标题
        site_title = '好医生运维'  # 此处设置页面头部标题
     
    admin_site = MyAdminSite(name='management')
    
    admin_site = MyAdminSite(name='management') 此处括号内name值必须设置,否则将无法使用admin设置权限
    
    注册的时候使用admin_site.register,而不是默认的admin.site.register
    
    from django.contrib import admin
    from hys_operation.models import *
    
    admin.site.site_header = '修改后'
    admin.site.site_title = '哈哈'
    
     不继承 admin.AdminSite 了,直接用admin.site 下的 site_header 和 site_title 
    

    当前用户过滤显示数据:

    @admin.register(MachineInfo)
    class MachineInfoAdmin(admin.ModelAdmin):
     
        def get_queryset(self, request):
            """函数作用:使当前登录的用户只能看到自己负责的服务器"""
            qs = super(MachineInfoAdmin, self).get_queryset(request)
            if request.user.is_superuser:
                return qs
            return qs.filter(user=UserInfo.objects.filter(user_name=request.user))
     
        list_display = ('machine_ip', 'application', 'colored_status', 'user', 'machine_model', 'cache',
                        'cpu', 'hard_disk', 'machine_os', 'idc', 'machine_group')
        
     ---> 功能: 不同用户·后得到不同界面
    

    编辑页设置:

    ManyToMany多对多字段设置。可以用filter_horizontal或filter_vertical:
    
    #Many to many 字段
    filter_horizontal=('tags',)
    
    用fields或exclude控制显示或者排除的字段,二选一即可
    fields =  ('caption', 'author', 'tags', 'content')
    或者
    
    exclude = ('recommend',) #排除该字段
    两个字段放在同一行可以如下设置:
    
    fields =  (('caption', 'author'), 'tags', 'content')
    

    关联字段:

    fieldsets。该设置可以对字段分块,看起来比较整洁
    
    fieldsets = (
        ("base info", {'fields': ['caption', 'author', 'tags']}),
        ("Content", {'fields':['content', 'recommend']})
    )
    
    
    一对多:
    订单主表(BillMain),记录主要信息;一个是订单明细(BillSub),记录购买商品的品种和数量等
    
    from django.contrib import admin
    from bill.models import BillMain, BillSub
     
    @admin.register(BillMain)
    class BillMainAdmin(admin.ModelAdmin):
        inlines = [BillSubInline,]    #Inline把BillSubInline关联进来
        list_display = ('bill_num', 'customer',)
        
    class BillSubInline(admin.TabularInline):
        model = BillSub
        extra = 5 #默认显示条目的数量
    

    设置只读:

    class MachineInfoAdmin(admin.ModelAdmin):
     
        def get_readonly_fields(self, request, obj=None):
            """  重新定义此函数,限制普通用户所能修改的字段  """
            if request.user.is_superuser:
                self.readonly_fields = []
            return self.readonly_fields
         
        readonly_fields = ('machine_ip', 'status', 'user', 'machine_model', 'cache',
                           'cpu', 'hard_disk', 'machine_os', 'idc', 'machine_group')
    

    数据保存操作:

    重写ModelAdmin的save_model实现:
        
        def save_model(self, request, obj, form, change):
        """  重新定义此函数,提交时自动添加申请人和备案号  """
     
        def make_paper_num():
            """ 生成随机备案号 """
            import datetime
            import random
            CurrentTime = datetime.datetime.now().strftime("%Y%m%d%H%M%S")  # 生成当前时间
            RandomNum = random.randint(0, 100)  # 生成的随机整数n,其中0<=n<=100
            UniqueNum = str(CurrentTime) + str(RandomNum)
            return UniqueNum
     
        obj.proposer = request.user
        obj.paper_num = make_paper_num()
        super(DataPaperStoreAdmin, self).save_model(request, obj, form, change)
        
        添加数据时,会自动保存申请人和备案号
    

    获取修改数据时获取保存前的数据:

    change参数,可以判断是修改还是新增,同时做相应的操作
    
    def save_model(self, request, obj, form, change):
        if change:  # 更改的时候
            machine_code = self.model.objects.get(pk=obj.pk).machine
            disk_id = self.model.objects.get(pk=obj.pk).disk_id
            disk_code = self.model.objects.get(pk=obj.pk).disk
            machine.Device.objects.filter(pk=disk_id).update(device_status='待报废')
            data = {'server_code': machine_code,
                    'device_type': '硬盘',
                    'original_code': disk_code,
                    'way': '变更',
                    'current_code': obj.disk}
            common.DeLog.objects.create(**data)  # 创建日志
        else:  # 新增的时候
            data = {'server_code': obj.machine,
                    'device_type': '硬盘',
                    'original_code': '',
                    'way': '新增',
                    'current_code': obj.disk}
            common.DeLog.objects.create(**data)  # 创建日志
        super(MachineExDiskAdmin, self).save_model(request, obj, form, change)
    

    删除操作:

    def delete_model(self, request, obj):
        machine.Device.objects.filter(pk=obj.pk).update(device_status='待报废')
        data = {'server_code': obj.machine,
                'device_type': '硬盘',
                'original_code': obj.disk,
                'way': '删除',
                'current_code': '',
                'user_name': request.user}
        common.DeLog.objects.create(**data)  # 创建日志
        super(MachineExDiskAdmin, self).delete_model(request, obj)
    

    限制:

    def get_readonly_fields(self, request, obj=None):
        """  重新定义此函数,限制普通用户所能修改的字段  """
        if request.user.is_superuser:
            self.readonly_fields = ['commit_date', 'paper_num']
        elif hasattr(obj, 'is_sure'):
            if obj.is_sure:
                self.readonly_fields = ('project_name', 'to_mail', 'data_selected', 'frequency', 'start_date',
                                        'end_date')
        else:
            self.readonly_fields = ('paper_num', 'is_sure', 'proposer', 'sql', 'commit_date')
     
        return self.readonly_fields
     
    def change_view(self, request, object_id, form_url='', extra_context=None):
        change_obj = DataPaperStore.objects.filter(pk=object_id)
        self.get_readonly_fields(request, obj=change_obj)
        return super(DataPaperStoreAdmin, self).change_view(request, object_id, form_url, extra_context=extra_context)
    

    修改显示:

    修改app的显示名称:
        	在应用的__init__.py里面进行修改即可:
    from django.apps import AppConfig
    import os
     
     
    default_app_config = 'hys_operation.PrimaryBlogConfig'
     
    VERBOSE_APP_NAME = u"1-本地服务器资源"
     
     
    def get_current_app_name(_file):
        return os.path.split(os.path.dirname(_file))[-1]
     
     
    class PrimaryBlogConfig(AppConfig):
        name = get_current_app_name(__file__)
        verbose_name = VERBOSE_APP_NAME
    

    自定义列表字段:

    	DataPaperStore模型中有 end_date 字段,如果当前时间大于end_date 是我们想显示一个“已过期”,但admin列表显示不能直接用该字段,也显示不出来。此时可以通过自定义列表字段显示
        
        def expired(self, ps):
        """自定义列表字段, 根据数据单截止日期和当前日期判断是否过期,并对数据库进行更新"""
        import datetime
        from django.utils.html import format_html
        end_date = ps.end_date
        if end_date >= datetime.date.today():
            ret = '未过期'
            color_code = 'green'
        else:
            ret = '已过期'
            color_code = 'red'
        DataPaperStore.objects.filter(pk=ps.pk).update(is_expired=ret)
        return format_html(
                    '<span style="color: {};">{}</span>',
                    color_code,
                    ret,
                )
    expired.short_description = '是否已过期'
    
    
    expired.admin_order_field = 'end_date'  # 使自定义字段 可以通过单击进行排序
    

    筛选:

    class MyModelAdmin(admin.ModelAdmin):
        def formfield_for_foreignkey(self, db_field, request, **kwargs):
            if db_field.name == "car":
                kwargs["queryset"] = Car.objects.filter(owner=request.user)
            return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
    

    admin 扩展:

    	默认的django会自动根据我们定义的模型生成form给admin使用,使用到这个form的地方分别是change和add
        
        admin.py:
            
    class RecordAdmin(admin.ModelAdmin):
        change_form_template = 'admin/extras/record_change_form.html'
        
     --> 使用change_form_template 重置 change_form所使用得模版
    
    配置的路径下新建html文件 record_change_form.html:
        {% extends "admin/change_form.html" %}
    {% load i18n admin_urls static admin_modify %}
     
    {% block extrahead %}{{ block.super }}
    <script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
        <script>
            django.jQuery(function() {
                var select = django.jQuery("#id_machine_room_id");
                console.log(select);
                select.change(function(){
    {#                console.log("value change"+django.jQuery(this).val());#}
                    var url = "/report/sub_servers/"+django.jQuery(this).val();//能够正确的访问到view的url
    {#                console.log(url);#}
                    django.jQuery.get(
                        url,
                        function(data){
                            var target = django.jQuery("#id_server_ip_id");
                            target.empty();//先要清空一下
                            data.forEach(function(e){
                                // 将从view得到的id和db_user名称赋值给db_server的select
                                console.log(e,e.id,e.name);
                                target.append("<option value='"+e.id+"'>"+e.name+"<option>");
                                target.eq(0).attr('selected', 'true');
                            });
                    })
                });
     
            });
        </script>
    {#{{ media }}#}
    {% endblock %}
    
    from django.conf.urls import url
    from hys_operation import views
     
    urlpatterns = [
        # url(r'^sub_users/(?P<obj_id>d+)', views.get_sub_users),
        url(r'^sub_servers/(?P<obj_id>d+)', views.get_sub_servers),
    ]
    

    view.py:

    def get_sub_servers(request, obj_id):
        # 查找此机房id下的ip
        servers = MachineInfo.objects.filter(idc=obj_id)
        result = []
        for i in servers:
            # 对应的id和ip组成一个字典
            result.append({'id': i.id, 'name': i.machine_ip})
        # 返回json数据
        return HttpResponse(json.dumps(result), content_type="application/json")
    

    案列:

    @admin.register(AmountChangeRecord)
    class AmountChangeRecordAdmin(AutoUpdateUserModelAdmin):
        readonly_fields = ['current_amounts', 'created_by', 'confirmed_by', 'datetime_created', 'datetime_updated']
        list_display = [
            'pk', 'customer', 'amounts', 'current_amounts', 'notes',
            'created_by', 'confirmed_by', 'datetime_created', 'datetime_updated']
        list_display_links = ['pk', 'customer', 'amounts', 'current_amounts', 'notes']
        search_fields = ['customer__name', 'customer__mobile']
        autocomplete_fields = ['customer']
        fieldsets = (
            (_('基础信息'), {'fields': ('customer', 'amounts', 'current_amounts', 'notes')}),
            (_('操作记录'), {'fields': ('created_by', 'confirmed_by', 'datetime_created', 'datetime_updated')})
        )
    
        
            def save_execl(self, request, queryset):
            filename = 'media/{0}_{1}.xls'.format('amounts', datetime.datetime.now().strftime('%Y%m%d%H%M%S'))
            headers = [
                'ID', '姓名', '手机号', '金额变更', '变更后余额', '创建人员', '最后变更人员', '创建日期', '最后更新时间']
            columns = [
                'pk', 'customer__name', 'customer__mobile', 'amounts', 'current_amounts',
                'created_by__full_name', 'confirmed_by__full_name', 'datetime_created', 'datetime_updated']
            return export_excel(queryset, headers, columns, filename)
    
        save_execl.short_description = "导出Excel"
    
        actions = [save_execl]
    
        
        ---> 方法构建的 Excel 导出功能只有在勾选了数据以后才能导出数据。
    
  • 相关阅读:
    python基础
    python基础
    python基础
    在hive下使用dual伪表
    mariadb 压缩包gz安装方式
    linux下 mysql5.7.20安装(精华)
    在开启kerberos 后,hbase存在数据命名空间的问题(解决方案)
    LINUX下解决TIME_WAIT等网络问题
    常用Oracle进程资源查询语句(运维必看)
    linux 下oracle 11g静默安装(完整版)
  • 原文地址:https://www.cnblogs.com/shaozheng/p/12889928.html
Copyright © 2011-2022 走看看