django-admin常用知识点记录

发布时间 2023-03-23 13:25:03作者: super_ip

1,格式化时间

def showtime(self):
 return self.create_time.strftime('%Y/%m/%d')
showtime.short_description="创建时间"  #更改列名,否则显示的是showtime名称
showtime.admin_order_field="create_time" #指定方法的数据按照模型的字段排序

2,获取关联数据

#获取关联数据,以 1,2,3,列表格式显示
def hero_link(self):
 return [ obj.hname for obj in self.hero.all()]


#实例:
@admin.register(Hero)
class HeroAdmin(admin.ModelAdmin, ExportCsvMixin):
   ...
   def children_display(self, obj):
       return ", ".join([
           child.name for child in obj.children.all()
      ])
   children_display.short_description = "Children"

3,获取关联数据统计:跟进次数统计

 #在销售机会表models.py下填写
 def follow_num(self):
       num=FollowList.objects.filter(user=self.pk,status=2).count()
       return  num
   follow_num.short_description="跟进次数"

4,详情页竖直列表样式

class HeroInfoStackInline(admin.StackedInline):
 model=HeroInfo #要编辑的对象
 extra =1 #附加编辑的数量
 
 
 inlines=[HeroInfoStackInline] #继承

5,客服归属问题

#此处可自动选择登录用户为归属客服,避免可看到后台所有用户名
  #除超级管理员,其他人只能看到自己
   def formfield_for_foreignkey(self, db_field, request, **kwargs):
           if db_field.name == 'kefu' and not request.user.is_superuser:
               kwargs['queryset'] = models.UserProfile.objects.filter(username=request.user.username)
           return super(SalesOpportunityAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
#除超级管理员,其他人只能看到自己
   def get_readonly_fields(self, request, obj=None):
           if obj is not None and not request.user.is_superuser:
               return self.readonly_fields + ('kefu',)
           return self.readonly_fields

   def add_view(self, request, form_url="", extra_context=None):
           data = request.GET.copy()
           data['kefu'] = request.user.username
           request.GET = data
           return super(SalesOpportunityAdmin, self).add_view(request, form_url="", extra_context=extra_context)  
       

 

6,通过get_redonly_fields动态获取只读字段

readonly_fields=('operator','modified')

def get_readonly_fields(self,request,obj=None):
 #如果实例存在,则修改。某些字段不允许修改
 if obj:
   return ('stock','gift','op','amount','operator','modified')
 #如果实例不存在,则新增。某些字段不允许修改
else:
   return self.readonly_fields

7,显示单选按钮radio模式

  #可以让性别处显示的是单选按钮radio模式
   radio_fields={
        'gender':admin.HORIZONTAL,
  }

 

8,自定义按钮

   @admin.display(ordering="username", description="操作")
   def operate(self):
       # 新标签中打开修改界面,url可以随意指定
       data = '{"name":"%s","icon":"fas fa-user-tie","url":"/admin/app01/userprofile/%d/change/"}' % (
           self.username, self.pk)
btn1 = f"""<button onclick='self.parent.app.openTab({data})' class='el-tag el-tag--small el-tag--dark'><i class="el-icon-edit"></i>修改</button>"""
     
       return mark_safe(f"<div> {btn1} </div>")


"""

9,如何在Django admin中优化查询?

旧的

@admin.register(Origin)
class OriginAdmin(admin.ModelAdmin):
   list_display = ("name", "hero_count", "villain_count")
   def hero_count(self, obj):
       return obj.hero_set.count()
   def villain_count(self, obj):
       return obj.villain_set.count()

新的

@admin.register(Origin)
class OriginAdmin(admin.ModelAdmin):
   list_display = ("name", "hero_count", "villain_count")
   def get_queryset(self, request):
       queryset = super().get_queryset(request)
       queryset = queryset.annotate(
           _hero_count=Count("hero", distinct=True),
           _villain_count=Count("villain", distinct=True),
      )
       return queryset
   def hero_count(self, obj):
       return obj._hero_count
   def villain_count(self, obj):
       return obj._villain_count

10,在用户详情页头像处显示图片,插件模式

参考链接:https://www.likecs.com/ask-376823.html

需要导入的库

from django.db import models
from django.contrib.admin.widgets import AdminFileWidget

插件代码admin.py中

class CustomAdminFileWidget(AdminFileWidget):
   def render(self, name, value, attrs=None, renderer=None):
       result = []
       if hasattr(value, "url"):
           result.append(
               f'''<a href="{value.url}" target="_blank">
                    <img
                      src="{value.url}" alt="{value}"
                      width="100" height="100"
                     
                    />
                  </a>'''
          )
       result.append(super().render(name, value, attrs, renderer))
       return format_html("".join(result))

 

在对应的userprofileadmin的添加

 formfield_overrides = {           # Here
       models.models.ImageField: {"widget": CustomAdminFileWidget}
  }

11,归属客服显示真实姓名:

    def full_name(self):
       return  self.last_name+self.first_name
   def __str__(self):
       return self.full_name()
   #外键在调用的时候显示的是姓名而非用户名
   

 

12,多选框的使用

第一种方法:

其中主要使用了MultiSelectField模块,模块项目地址:https://github.com/goinnn/django-multiselectfield

models.py:

from django.db import models
from multiselectfield import MultiSelectField

# Create your models here.
pip install django-multiselectfield

class test_table(models.Model):
   language_choices = (('chinese', u'汉语'), ('english', u'英语'), ('french', '法语'))
   language = MultiSelectField(u"使用语言", choices=language_choices,null=True

 

第二种方法:

def formfield_for_manytomany(self, db_field, request=None, **kwargs):
   if db_field.name == 'your field name':
       kwargs['widget'] = form_widgets.CheckboxSelectMultiple()
       kwargs['help_text'] = ''

   return db_field.formfield(**kwargs)

13,正整数模型

PositiveIntegerField

#IntegerField一样,但只包含正整数

14,数字验证,手机号码验证,不允许负数

在models.py模型中

validators=[RegexValidator(r'^[0-9]+$')]
validators=[RegexValidator(r'^1[356789]\d{9}$', "手机号码格式不正确")],

PositiveSmallIntegerField 正整数

 

15,自定义字段判断:

def colored_status(self):
   if self.status_id == 5:
       color_code = 'el-tag el-tag--small el-tag--danger el-tag--dark'
   elif self.status_id == 4:
       color_code = 'el-tag el-tag--small el-tag--success el-tag--dark'
   else:
       color_code = 'el-tag el-tag--small el-tag--dark'
   return format_html(
       '<span class="{}">{}</span>',
       color_code,
       self.status.name,
  )


colored_status.short_description = u"状态"

16,除管理员外,其他用户只返回自己名下数据

  def get_queryset(self, request):
       qs = super(EnterpriseUsersAdmin, self).get_queryset(request)
       if request.user.is_superuser:
           return qs
       return qs.filter(kefu=request.user)

 

17,隐藏按钮

def get_actions(self, request):
       actions = super().get_actions(request)
       if not request.user.is_superuser:
           if 'custom_button' in actions:
               del actions['custom_button']
       return actions