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 導出功能只有在勾選了數據以后才能導出數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM