zoukankan      html  css  js  c++  java
  • admin的基础配置

    admin自定义配置

    一、admin.py

    我们知道在models.py文件中创建的数据表,一方面我们可以通过视图函数对其进行增删改查,一方面我们也可以通过admin进行,通常我们是通过admin的前端页面进行增删改查。这里我们在后端admin.py文件中进行。

    1.admin.site.register

    用admin对数据表的操作都需要在每个APP项目中的admin.py文件中将你需要处理的表名admin.site.register(表名)导入

    创建OK后现在进入admin的页面进行操作:

    2.admin的增删改查的url规律:

    通过admin对UserInfo表进行增删改查可知其url的变化的规律如下所示:

    	 自动生成URL
    		/admin/app01/userinfo/   			 	列表 change_list_view
    		/admin/app01/userinfo/add/  			增加 方法
    		/admin/app01/userinfo/2/change/			修改 方法
    		/admin/app01/userinfo/2/delete/			删除 方法
    

    执行到这一步我们会有疑问,如此多的url,而在Django的url的配置文件中却只有下面这行代码:

    from django.conf.urls import url
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    ]
    

    这里我们猜想在执行路由分发之前url(r'^admin/', admin.site.urls),它一定先做了什么事。

    3.admin中的配置方法

    1.单字段显示字段文本名:

    class UserInfo(models.Model):
        name = models.CharField(max_length=32)
        email = models.EmailField(max_length=32)
        def __str__(self):
            return self.name
    

    效果如下图所示:

    2.多字段文本显示:

    admin在__str__的默认方式中提供的只有单字段的文本显示,但是通过admin.py文件我们可以自定义多字段的文本显示如下:

    from django.contrib import admin
    from . import models
    
    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email']     #list_display即在admin的页面中显示的字段
    admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法
    

    执行后的效果如下图所示:

    这里我们需要注意的是list_display这个列表中的字段既可以是数据表中既有的字段也可以是自定义的字段,如下代码即可实现:

    from django.contrib import admin
    from . import models
    
    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email','whatmini']     #list_display即在admin的页面中显示的字段
        
        def whatmini(self,obj):     #自定义显示的字段
    
            return "hello"
    
    admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法
    

    执行的效果如下图所示:

    当需要自定义字段显示时,需要创建以显示字段为函数名的函数,并带有return值的函数,上述whatmini代码中的另一个参数obj,是当前数据对象
    如下将代码修改执行:

    def whatmini(self,obj):     #自定义显示的字段
        print(obj)
        return obj.name
    

    下面是执行的结果

    October 18, 2017 - 16:48:24
    Django version 1.11.4, using settings 'lijianCrm.settings'
    Starting development server at http://127.0.0.1:8000/
    Quit the server with CTRL-BREAK.
    UserInfo object
    UserInfo object
    

    下面是前端admin页面的显示效果:

    所以通过这个自定义的我们可以做很多的事情如可以将字段变成a标签:

    from django.contrib import admin
    from . import models
    from django.utils.safestring import mark_safe
    
    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email','whatmini']     #list_display即在admin的页面中显示的字段
    
        def whatmini(self,obj):     #自定义显示的字段
            tp1= "<a href=http://www.cnblogs.com/lijian-22huxiaoshan/>{0}</a>".format(obj.name)
            return mark_safe(tp1)
    
    admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法
    

    admin前端页面显示效果如下:

    需要了解的是,admin.ModelAdmin是admin对每个数据表执行的一个默认的配置,其源码如下

    register源码

    通过register的源码可以知道 model_or_iterable这个参数可以是列表

     def register(self, model_or_iterable, admin_class=None, **options):
        """
        Registers the given model(s) with the given admin class.
    
        The model(s) should be Model classes, not instances.
    
        If an admin class isn't given, it will use ModelAdmin (the default
        admin options). If keyword arguments are given -- e.g., list_display --
        they'll be applied as options to the admin class.
    
        If a model is already registered, this will raise AlreadyRegistered.
    
        If a model is abstract, this will raise ImproperlyConfigured.
        """
        if not admin_class:
            admin_class = ModelAdmin
    
        if isinstance(model_or_iterable, ModelBase):  #当model_or_iterable 是列表时执行下面代码
            model_or_iterable = [model_or_iterable]
    

    即可以在admin.py中的代码可以改成下面操作:

    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email','whatmini']     #list_display即在admin的页面中显示的字段
    
        def whatmini(self,obj):     #自定义显示的字段
            tp1= "<a href=http://www.cnblogs.com/lijian-22huxiaoshan/>{0}</a>".format(obj.name)
            return mark_safe(tp1)
    
    admin.site.register([models.UserInfo,"第二张表","第三张表",....],foo)    #表示在admin在处理UserInfo中执行foo中的方法
    

    这里三张表都可以执行foo函数的方法。

    同时也可以通过装饰器的方式进行:

    from django.contrib import admin
    from . import models
    from django.utils.safestring import mark_safe
    
    @admin.register(models.UserInfo)
    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email','whatmini']     #list_display即在admin的页面中显示的字段
    
        def whatmini(self,obj):     #自定义显示的字段
            tp1= "<a href=http://www.cnblogs.com/lijian-22huxiaoshan/>{0}</a>".format(obj.name)
            return mark_safe(tp1)
    

    ModelAdmin源码:

    3.list_display_links方法:

    list_display_links,列表时,定制列可以点击跳转。

    from django.contrib import admin
    from . import models
    from django.utils.safestring import mark_safe
    
    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email']     #list_display即在admin的页面中显示的字段
        list_display_links = ['name','email']
    
    
    admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法
    

    4.list_filter,列表时,定制右侧快速筛选

    from django.contrib import admin
    from . import models
    from django.utils.safestring import mark_safe
    
    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email']     #list_display即在admin的页面中显示的字段
        list_display_links = ['name','email']
        list_filter = ['name','group']  
    
    admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法
    admin.site.register(models.UserGroup)
    

    当这里的UserInfo和第三张表进行ForeignKey关联时也会将第三张表的数据显示如下:

    也可以通过下面的代码进行定制:

    from django.contrib import admin
    from . import models
    from django.utils.safestring import mark_safe
    from django.utils.translation import ugettext_lazy as _
    
    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email']     #list_display即在admin的页面中显示的字段
        list_display_links = ['name','email']
    
    
        class Ugg(admin.SimpleListFilter):
            title = _('角色组')
            parameter_name = 'xxxxxx'
    
            def lookups(self, request, model_admin):
                """
                显示筛选选项
                :param request:
                :param model_admin:
                :return:
                """
                return models.UserGroup.objects.values_list('id', 'title')   #前端显示的筛选条件
    
            def queryset(self, request, queryset):
                """
                点击查询时,进行筛选
                :param request:
                :param queryset:
                :return:
                """
                v = self.value()
                return queryset
    
    
        list_filter = ['name',Ugg]
    
    
    admin.site.register(models.UserInfo,foo)    #表示在admin在处理UserInfo中执行foo中的方法
    
    admin.site.register(models.UserGroup)
    

    5.list_select_related,列表时,连表查询是否自动select_related

    6.分页

    # 分页,每页显示条数
        list_per_page = 100
     
    # 分页,显示全部(真实数据<该值时,才会有显示全部)
        list_max_show_all = 200
     
    # 分页插件
        paginator = Paginator
    

    7.list_editable,列表时,可以编辑的列

    	@admin.register(models.UserInfo)
    	class UserAdmin(admin.ModelAdmin):
    	    list_display = ('user', 'pwd','ug',)
    	    list_editable = ('ug',)
    

    8.search_fields,列表时,模糊搜索的功能

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
         
        search_fields = ('user', 'pwd')
    

    9.date_hierarchy,列表时,对Date和DateTime类型进行搜索

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
     
        date_hierarchy = 'ctime'
    

    需要注意的是该方法需要数据表中有时间的字段

    10.preserve_filters,详细页面,删除、修改,更新后跳转回列表后,是否保留原搜索条件

    11.save_as = False,详细页面,按钮为“Sava as new” 或 “Sava and add another”

    12.save_as_continue = True,点击保存并继续编辑

    save_as_continue = True

    # 如果 save_as=True,save_as_continue = True, 点击Sava as new 按钮后继续编辑。
    # 如果 save_as=True,save_as_continue = False,点击Sava as new 按钮后返回列表。
     
    New in Django 1.10.
    

    13.save_on_top = False,详细页面,在页面上方是否也显示保存删除等按钮

    14.inlines,详细页面,如果有其他表和当前表做FK,那么详细页面可以进行动态增加和删除

    class UserInfoInline(admin.StackedInline): # TabularInline这个也可以继承功能和StackedInline的功能一样只是显示方式不同而已
        extra = 0
        model = models.UserInfo
    class UserGroupAdmin(admin.ModelAdmin):
        list_display = ['title',]
        inlines = [UserInfoInline, ]
    admin.site.register(models.UserGroup,UserGroupAdmin)
    

    admin前端页面的显示效果如下:

    这里需要注意的是,ForeignKey字段在在哪个表则上述代码只能关联另外的表不能关联FK字段所在的那张表

    15.action,列表时,定制action中的操作

    代码如下:

    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email']     #list_display即在admin的页面中显示的字段
        list_display_links = ['name','email']
    
        def func(self,request,queryset):
            pass
        actions = [func,]
    

    所以这里通过func我们可以做自定义的操作如下:

    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email']     #list_display即在admin的页面中显示的字段
        list_display_links = ['name','email']
    
        def func(self,request,queryset):
            print(request.POST.getlist('_selected_action'))
            print('代码来了')
        actions = [func,]
        func.short_description = "中文显示自定义Actions"
    

    执行结果:

    [18/Oct/2017 19:26:58] "GET /static/admin/img/tooltag-add.svg HTTP/1.1" 304 0
    ['2', '1']
    代码来了
    [18/Oct/2017 19:27:08] "POST /admin/app01/userinfo/ HTTP/1.1" 302 0
    

    16.定制HTML模板

    change_list_template页面

    除了change_list_template页面admin中还有以下页面:

    add_form_template = None   #添加页面
    change_form_template = None #编辑页面
    delete_confirmation_template = None #删除页面
    delete_selected_confirmation_template = None  #删除确认页面
    object_history_template = None   #删除显示记录页面
    

    17.raw_id_fields,详细页面,针对FK和M2M字段变成以Input框形式

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
     
        raw_id_fields = ('FK字段', 'M2M字段',)
    

    18.fields,详细页面时,显示字段的字段

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
        fields = ('user',)
    

    19.exclude,详细页面时,排除的字段

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
        exclude = ('user',)
    

    20.readonly_fields,详细页面时,只读字段

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
        readonly_fields = ('user',)
    

    21.fieldsets,详细页面时,使用fieldsets标签对数据进行分割显示

    	@admin.register(models.UserInfo)
    	class UserAdmin(admin.ModelAdmin):
        fieldsets = (
            ('基本数据', {
                'fields': ('user', 'pwd', 'ctime',)
            }),
            ('其他', {
                'classes': ('collapse', 'wide', 'extrapretty'),  # 'collapse','wide', 'extrapretty'
                'fields': ('user', 'pwd'),
            }),
        )
    

    22.详细页面时,M2M显示时,数据移动选择(方向:上下和左右)

    代码如下:

    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email']     #list_display即在admin的页面中显示的字段
        list_display_links = ['name','email']
    
        def func(self,request,queryset):
            print(request.POST.getlist('_selected_action'))
            print('代码来了')
        actions = [func,]
        func.short_description = "中文显示自定义Actions"
    
        filter_horizontal = ("roles",)
    

    这里需要注意关联数据表要有ManyToManyField的字段

    23.ordering,列表时,数据排序规则

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
        ordering = ('-id',)
        或
        def get_ordering(self, request):
            return ['-id', ]  #从小到大排
    

    24.view_on_site,编辑时,是否在页面上显示view on set

    class foo(admin.ModelAdmin):      #自定义需要继承admin.ModelAdmin
        list_display = ['name','email']     #list_display即在admin的页面中显示的字段
        list_display_links = ['name','email']
    
        def func(self,request,queryset):
            print(request.POST.getlist('_selected_action'))
            print('代码来了')
        actions = [func,]
        func.short_description = "中文显示自定义Actions"
    
        filter_horizontal = ("roles",)
    
        def view_on_site(self,obj):
            return 'https://www.baidu.com'
    

    25.radio_fields,详细页面时,使用radio显示选项(FK默认使用select)

    radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL
    

    26.show_full_result_count = True,列表时,模糊搜索后面显示的数据个数样式

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
        # show_full_result_count = True # 1 result (12 total)
        # show_full_result_count = False  # 1 result (Show all)
        search_fields = ('user',)
    

    27.formfield_overrides = {},详细页面时,指定现实插件

    from django.forms import widgets
    from django.utils.html import format_html
     
    class MyTextarea(widgets.Widget):
        def __init__(self, attrs=None):
            # Use slightly better defaults than HTML's 20x2 box
            default_attrs = {'cols': '40', 'rows': '10'}
            if attrs:
                default_attrs.update(attrs)
            super(MyTextarea, self).__init__(default_attrs)
     
        def render(self, name, value, attrs=None):
            if value is None:
                value = ''
            final_attrs = self.build_attrs(attrs, name=name)
            return format_html('<textarea {}>
    {}</textarea>',final_attrs, value)
     
     
     
    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
     
        formfield_overrides = {
            models.models.CharField: {'widget': MyTextarea},
        }
    

    28.prepopulated_fields = {},添加页面,当在某字段填入值后,自动会将值填充到指定字段。

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
     
        prepopulated_fields = {"email": ("user","pwd",)}
    

    29.form = ModelForm,用于定制用户请求时候表单验证

    from app01 import models
    from django.forms import ModelForm
    from django.forms import fields
     
     
    class MyForm(ModelForm):
        others = fields.CharField()
     
        class Meta:
            model = models = models.UserInfo
            fields = "__all__"
     
    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
     
        form = MyForm 
    

    30.empty_value_display = "列数据为空时,显示默认值"

    @admin.register(models.UserInfo)
    class UserAdmin(admin.ModelAdmin):
        empty_value_display = "列数据为空时,默认显示"
     
        list_display = ('user','pwd','up')
     
        def up(self,obj):
            return obj.user
        up.empty_value_display = "指定列数据为空时,默认显示"
  • 相关阅读:
    [树形dp] Luogu P4516 潜入行动
    [kruskal][Trie] Codeforces 888G Xor-MST
    [线性基] Luogu P4151 最大XOR和路径
    [线段树] Luogu P4560 砖墙
    [递归][重心] Luogu P4886 快递员
    [Trie][贪心][堆] LibreOJ #3048 异或粽子
    [长链剖分][优先队列] LibreOJ #3052 春节十二响
    [支配树] Bzoj P2815 灾难
    [长链剖分][线段树] Bzoj P1758 重建计划
    [dsu on tree] Codeforces 600E Lomsat gelral
  • 原文地址:https://www.cnblogs.com/lijian-22huxiaoshan/p/7688653.html
Copyright © 2011-2022 走看看