class PostAdmin(BaseOwnerAdmin): # 自定义Form(desc摘要字段) form = PostAdminForm list_display = [ 'title', 'category', 'status', 'created_time', 'operator', 'owner' ] list_display_links = [] list_filter = ['category'] search_fields = ['title', 'category__name'] actions_on_top = True actions_on_bottom = True # 编辑页面 save_on_top = True # 限定要展示的字段、字段的顺序 # fields = ( # ('category', 'title'), # 'desc', # 'status', # 'content', # 'tag', # ) # 控制页面的布局 form_layout = ( Fieldset( '基础信息', Row("title", "category"), 'status', 'tag', ), Fieldset( '内容信息', 'desc', 'content', ) ) filter_horizontal = ('tag',) # 多对多控制横竖布局 def operator(self, obj): return format_html( '<a href="{}">编辑</a>', reverse('xadmin:blog_post_change', args=(obj.id,)) ) operator.short_description = '操作' # 表头展示名字 """
class PostAdmin(BaseOwnerAdmin): form = PostAdminForm list_display = [ 'title', 'category', 'status', 'created_time', 'owner', 'operator' ] list_display_links = [] list_filter = [ 'category', ] search_fields = ['title', 'category__name'] save_on_top = True actions_on_top = True actions_on_bottom = True # 编辑页面 save_on_top = True exclude = ['owner'] form_layout = (Fieldset( '基础信息', Row("title", "category"), 'status', 'tag', ), Fieldset( '内容信息', 'desc', 'is_md', 'content_ck', 'content_md', 'content', )) def operator(self, obj): return format_html('<a href="{}">编辑</a>', reverse('xadmin:blog_post_change', args=(obj.id, ))) operator.short_description = '操作' @property def media(self): # xadmin基于bootstrap,引入会页面样式冲突,仅供参考, 故注释。 media = super().media media.add_js([ 'https://cdn.bootcss.com/bootstrap/4.0.0-beta.2/js/bootstrap.bundle.js' ]) media.add_css({ 'all': ("https://cdn.bootcss.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css", ), }) return media
class AuthapplyAdmin: list_display = ('name', 'position', 'type', 'is_passed', 'date_apply') list_filter = ('position', 'type', 'floor', 'date_apply') form_layout = (Main( Fieldset('申请内容', 'user', 'name', 'position', 'floor', 'type', 'date_apply'), ), Side(Fieldset( '状态控制', 'is_passed', )))
class ArticleAdmin(object): search_fields = ('title', 'summary') list_filter = ('status', 'category', 'is_top', 'create_time', 'update_time', 'is_top') list_display = ('title', 'category', 'author', 'status', 'is_top', 'update_time') form_layout = (Fieldset(u'基本信息', 'title', 'en_title', 'img', 'category', 'tags', 'author', 'is_top', 'rank', 'status'), Fieldset(u'内容', 'content'), Fieldset(u'摘要', 'summary'), Fieldset(u'时间', 'pub_time'))
class PostAdmin(BaseOwnerAdmin): form = PostAdminForm # 列表页 list_display = ('title', 'status', 'category', 'created_time', 'operator') list_display_links = [] list_filter = ['category'] search_fields = ['title', 'category__name'] # actions_on_bottom = True actions_on_top = True # 编辑页 save_on_top = True # fields = ( # ('title', 'category'), # 'desc', # 'content', # 'tag', # ) exclude = ['owner'] form_layout = (Fieldset( '基础信息', Row("title", "category"), 'status', 'tag', ), Fieldset( '内容信息', 'desc', 'is_md', 'content_ck', 'content_md', 'content', )) # filter_horizontal = ('tag', ) # filter_vertical = ('tag', ) # 自定义字段方法 def operator(self, obj): return format_html('<a href="{}">编辑</a>', reverse('xadmin:blog_post_change', args=(obj.id, ))) operator.short_description = '操作' def save_model(self, request, obj, form, change): obj.owner = request.user return super(PostAdmin, self).save_model(request, obj, form, change) def get_queryset(self, request): qs = super(PostAdmin, self).get_queryset(request) return qs.filter(owner=request.user)
class PostAdmin(BaseOwnerAdmin): form = PostAdminForm list_display = [ 'title', 'category', 'status', 'created_time', 'owner', 'operator' ] list_filter = ('category', ) search_fields = ['title', 'category__name'] actions_on_top = True """ 要求格式 fieldsets = ( ('名称',{ '配置一':xxx, '配置二':xxx }), ('名称',{}), ) 配置项有: - description: 描述<string> - fields: 显式字段顺序<tuple> - classes: 当前块儿的样式 <tuple> collapse 是单击展开可隐藏, wide 是常规显式 """ form_layout = ( Fieldset( '基础配置', Row('title', 'category'), 'status', 'tag', 'is_markdown', ), Fieldset( '内容', 'desc', 'content_ck', 'content_md', 'content', ), ) def operator(self, obj): return format_html('<a href="{}">编辑</a>', reverse('xadmin:blog_post_change', args=(obj.id, ))) operator.short_description = '操作' @property def media(self): """在Media信息中可以自定义静态资源的引入""" # xadmin 导入静态文件 media = super().media media.add_js([]) media.add_css({'all': []}) return media
class PostAdmin(BaseOwnerAdmin): form = PostAdminForm list_display = [ 'title', 'category', 'status', 'created_time', 'operator', ] exclude = ('owner', 'pv', 'uv') list_display_links = [] list_filter = ['category'] # 页面过滤器 search_fields = ['title', 'category__name'] # 配置搜索字段 actions_on_top = True actions_on_bottom = True # 编辑页面 save_on_top = True # 把保存,编辑,编辑并新建按钮展示在顶部 form_layout = (Fieldset( '基础信息', Row('title', 'category'), 'status', 'tag', ), Fieldset( '内容信息', 'desc', 'is_md', 'content_ck', 'content_md', 'content', )) filter_vertical = ('tag', ) def operator(self, obj): return format_html('<a href="{}">编辑</a>', self.model_admin_url('change', obj.id)) operator.short_description = '操作' def formfield_for_dbfield(self, db_field, **kwargs): if db_field.name == 'category': kwargs['queryset'] = Category.objects.filter( owner=self.request.user) elif db_field.name == 'tag': kwargs['queryset'] = Tag.objects.filter(owner=self.request.user) return super().formfield_for_dbfield(db_field, **kwargs)
class TagAdmin(CommonSetting): list_display = ('tag', 'is_active', 'art_nums', 'add', 'mod') search_fields = ('tag', ) list_filter = ('add', 'mod', 'is_active') readonly_fields = ('add', 'mod') form_layout = ( Main(Fieldset( _("标签信息"), Row('tag', 'art_nums'), Row('add', 'mod'), ), ), Side(Fieldset(_('状态'), 'is_active'), ), )
class ArticleAdmin(object): list_display = ('title', 'categories', 'date') list_display_links = ('title', ) search_fields = ('title', 'content') list_editable = ('date', ) list_filter = ('categories', 'date') form_layout = ( Fieldset('基本信息', 'title', 'date'), Fieldset('文章内容', Field('content', template="xcms/content_field.html")), ) style_fields = {'content': 'wysi_ck', 'categories': 'm2m_tree'}
class PostAdmin(BaseOwnerAdmin): form = PostAdminForm # <class 'article.admin.PostAdmin'>: (admin.E109) The value of 'list_display[3]' must not be a ManyToManyField. # list_display 不能包含ManyToMany字段 list_display = [ 'title', 'author', 'category', 'summary', 'pv', 'uv', 'created_time', 'operator' ] list_filter = ['category'] list_display_links = [ 'title', ] # 注意外键“分类”的编写 search_fields = ['title', 'category__name'] # 编辑页面不显示字段 exclude = ['author', 'pv', 'uv'] # 编辑界面 # save_on_top = True # 'created_time' cannot be specified for Post model form as it is a non-editable field. # 'created_time' 不能出现在fields中,因为他是不可编辑字段 # fields = (('category', 'title'), 'status', 'tag', 'summary', 'content') 替换为FieldsSet form_layout = ( Fieldset( '基础信息', Row('category', 'title'), 'status', ), Fieldset('内容信息', 'summary', 'is_markdown', 'content_ck', 'content_md', 'content'), Fieldset( '额外信息', # 'classes': ('collapse',), 'tag', )) # 多对多标签选择,水平显示 filter_horizontal = ('tag', ) # 多对多标签选择,垂直显示 filter_vertical = ('tag', ) # 自定义函数??? def operator(self, obj): return format_html( '<a href="{0}"> 编辑 </a>', reverse('xadmin:article_post_change', args=(obj.id, ))) operator.short_description = '操作'
class PlatformInfoAdmin(object): list_display = ['p_name', 'order_status', 'creator', 'create_time'] search_fields = ['p_name'] form_layout = [ Fieldset('必填信息', 'p_name', 'order_status'), Fieldset(None, 'creator', 'is_delete', **{"style": "display:None"}), ] def save_models(self): obj = self.new_obj request = self.request obj.creator = request.user.username obj.save() super(PlatformInfoAdmin, self).save_models()
def get_form_layout(self): if self.org_obj: self.form_layout = ( Main( Fieldset("", "username", "password", css_class="unsort no_title"), Fieldset( _("Personal info"), Row("first_name", "last_name"), "email" ), Fieldset(_("Permissions"), "groups", "user_permissions"), Fieldset(_("Important dates"), "last_login", "date_joined"), ), Side(Fieldset(_("Status"), "is_active", "is_staff", "is_superuser",),), ) return super(UserAdmin, self).get_form_layout()
def get_form_layout(self): if self.request.user.is_superuser: self.form_layout = Layout(Container(Col('full', Fieldset( "", "title", "content", "user", css_class="unsort no_title"), horizontal=True, span=12) )) else: self.form_layout = Layout(Container(Col('full', Fieldset( "", "title", "content", css_class="unsort no_title"), horizontal=True, span=12) )) return super(ArticleAdmin, self).get_form_layout()
def get_form_layout(self): if self.org_obj: self.form_layout = (Main( Fieldset('', 'username', 'password', css_class='unsort no_title'), Fieldset('其他字段', 'nickname', 'last_login'), Fieldset(_('Permissions'), 'groups', 'user_permissions'), ), Side( Fieldset(('Status'), 'is_active', 'is_superuser', 'is_deleted'), )) return super(UserAdmin, self).get_form_layout()
class MeetingAdmin(object): import_export_args = { 'import_resource_class': MeetingResource, 'export_resource_class': MeetingResource } list_display = [ 'id', 'name', 'gender', 'danwei', 'dishi', 'mobile', 'email' ] search_fields = ['name', 'gender', 'danwei', 'dishi'] list_filter = ['name', 'gender', 'danwei', 'dishi'] # 关闭书签功能 show_bookmarks = False # 设置载入自定义按钮,创建下载模板 meeting_allow = True # 排序使用 ordering = ['id'] # 输入框只读设置 # readonly_fields = ['user'] # 不在输入框显示设置 exclude = ['user'] def __unicode__(self): return self.name def save_models(self): self.new_obj.user = self.request.user self.new_obj.save() # #设计只能查看自己的创建的内容 def queryset(self): if not self.request.user.is_superuser: st = self.request.user sr = Meeting.objects.filter(user=st) return sr return Meeting.objects.all() #=================进行设置添加表单时的样式设置==================================== form_layout = ( Main( Fieldset('', 'name', 'gender', css_class='unsort no_title'), Fieldset('Personal info', Row('danwei', 'dishi'), 'mobile'), ), # Side( # Fieldset(_('Status'), # 'is_active', 'is_staff', 'is_superuser', # ), # ) )
def get_form_layout(self): """ 返回 Form Layout ,如果您设置了 :attr:`detail_layout` 属性,则使用 :attr:`form_layout` 属性,如果都没有该方法会自动生成 Form Layout 。 有关 Form Layout 的更多信息可以参看 `Crispy Form 文档 <http://django-crispy-forms.readthedocs.org/en/latest/layouts.html>`_ 设置 Form Layout 可以非常灵活的显示页面的各个元素 """ # 复制避免修改属性值 layout = copy.deepcopy(self.detail_layout or self.form_layout) if layout is None: layout = Layout( Container( Col('full', Fieldset("", *self.form_obj.fields.keys(), css_class="unsort no_title"), horizontal=True, span=12))) elif type(layout) in (list, tuple) and len(layout) > 0: # 如果设置的 layout 是一个列表,那么按以下方法生成 if isinstance(layout[0], Column): fs = layout elif isinstance(layout[0], (Fieldset, TabHolder)): fs = (Col('full', *layout, horizontal=True, span=12), ) else: fs = (Col('full', Fieldset("", *layout, css_class="unsort no_title"), horizontal=True, span=12), ) layout = Layout(Container(*fs)) if self.detail_show_all: # 显示没有在 Layout 中出现的字段 rendered_fields = [i[1] for i in layout.get_field_names()] container = layout[0].fields other_fieldset = Fieldset( _(u'Other Fields'), *[ f for f in self.form_obj.fields.keys() if f not in rendered_fields ]) if len(other_fieldset.fields): if len(container) and isinstance(container[0], Column): container[0].fields.append(other_fieldset) else: container.append(other_fieldset) return layout
class UserInfoAdmin(object): """ 充电(微信)用户 """ list_display = [ 'name', 'nickname', 'openid', 'telephone', 'car_type', 'total_money', 'consume_money', 'account_balance', 'is_freeze', 'balance_reset' ] search_fields = [ 'name', 'openid', 'telephone', 'nickname', 'pile_sn', 'car_type' ] list_filter = ['user_type', 'seller'] list_per_page = 50 reversion_enable = True use_related_menu = False style_fields = {"is_freeze": "radio-inline"} model_icon = 'fa fa-weixin' object_list_template = "wxchat/userinfo_model_list.html" form_layout = (Main( Fieldset('', Row('name', 'nickname'), Row('user_type', 'telephone'), Row('seller', 'openid'), Row('car_number', 'car_type'), Row('id_card', None), css_class='unsort no_title'), Fieldset( "微信公众号信息", 'subscribe', 'subscribe_time', Row('sex', 'subscribe_scene'), Row('country', 'province'), Row('city', 'language'), Row('headimgurl', 'qr_scene'), ), Fieldset( "其他信息", Row('last_charg_time', 'out_trade_no'), Row('visit_city', 'visit_time'), Row('is_freeze', 'freeze_time'), 'freeze_reason', )), Side( AppendedText('total_money', '元'), AppendedText('consume_money', '元'), AppendedText('binding_amount', '元'), AppendedText('consume_amount', '元'), ))
class Personneladmin(Baseadminmodel): mymodel = Personnel list_prefetch_related = ['equipment_bar_set__equipment__prgsheet__contract','subject_or_worktype'] model_icon = 'fa fa-book' list_filter = ['subject_or_worktype__name','equipment_bar__equipment__prgsheet__contract']+mymodel.get_fields() list_editable=['canreuse','islive'] form_layout = ( Fieldset((u'猎聘人才'), Row('name', 'num','gender'), Row('contact_man', 'tel'), 'major_type', 'subject_or_worktype', 'level', 'money', 'singman', Row('islive', 'canreuse'), Row('signdate', 'enddate'), 'comment', Row('createtime', 'updatetime', 'founder','company'), css_class='unsort'), Fieldset('相关附件', Row('file', 'file_to_pdf'), Row('zsfile', 'zsfile_to_pdf'), ), ) #在get_context之前,修改list_exclude数据 def get_context(self): caninfo=self.user.has_perm('%s.info_%s' % self.model_info) if not caninfo:self.list_exclude=['contact_man','tel','money','file','file_to_pdf'] return super().get_context() #这是detail/add/update/get的第一个操作,使用工厂制造一个modelform类, # 在这个操作更改后面要使用的exclude和form_layout def get_model_form(self, **kwargs): caninfo = self.user.has_perm('%s.info_%s' % self.model_info) if (not caninfo) and (not "add" in self.request.get_full_path()): self.exclude=['contact_man','tel','money','file','file_to_pdf'] self.form_layout=( Fieldset((u'猎聘人才'), Row('name', 'num','gender'), 'major_type', 'subject_or_worktype', 'level', 'singman', Row('islive', 'canreuse'), Row('signdate', 'enddate'), 'comment', Row('createtime', 'updatetime', 'founder','company'), css_class='unsort'), Fieldset('相关附件', Row('zsfile', 'zsfile_to_pdf'), ), ) return super().get_model_form( **kwargs)
class BannerModelAdmin(object): list_display = ('title', 'url', 'if_show', 'add_time') search_fields = ('title', ) list_filter = ('title', 'if_show', 'add_time') model_icon = 'fa fa-picture-o' form_layout = (Main( Fieldset('', 'title', 'image', 'url', 'add_time', 'index', css_class='unsort no_title'), ), Side(Fieldset('状态', 'if_show'), )) style_fields = {"desc": "ueditor"}
def get_form_layout(self): layout = copy.deepcopy(self.form_layout) arr = self.form_obj.fields.keys() if six.PY3: arr = [k for k in arr] fields = arr + list(self.get_readonly_fields()) if layout is None: layout = Layout( Container( Col( "full", Fieldset("", *fields, css_class="unsort no_title"), horizontal=True, span=12, ) ) ) elif type(layout) in (list, tuple) and len(layout) > 0: if isinstance(layout[0], Column): fs = layout elif isinstance(layout[0], (Fieldset, TabHolder)): fs = (Col("full", *layout, horizontal=True, span=12),) else: fs = ( Col( "full", Fieldset("", *layout, css_class="unsort no_title"), horizontal=True, span=12, ), ) layout = Layout(Container(*fs)) rendered_fields = [i[1] for i in layout.get_field_names()] container = layout[0].fields other_fieldset = Fieldset( _(u"Other Fields"), *[f for f in fields if f not in rendered_fields] ) if len(other_fieldset.fields): if len(container) and isinstance(container[0], Column): container[0].fields.append(other_fieldset) else: container.append(other_fieldset) return layout
class UndistributionAdmin(object): # 特别注意一下,就是源仓库是存货属性,之前命名搞懵逼了,结果代码写了多一半就不改了,自己备注下,将来不至于懵逼 list_display = [ 'order_status', 'error_tag', 'distribution_order_id', 'warehouse', 'department', 'goods_name', 'quantity', 'undistribution_q', 'available_q', 'memorandum', 'vwarehouse', 'creator', 'create_time', 'update_time' ] list_filter = [ 'creator', 'order_status', 'warehouse__warehouse__warehouse_name', 'department__name', 'goods_name__goods_name', 'quantity', 'memorandum', 'vwarehouse__warehouse_name', 'create_time', 'update_time' ] list_editable = ['quantity'] actions = [ OriDOAction, ] form_layout = [ Fieldset('必填信息', 'goods_name', "warehouse", "quantity", "department", 'goods_name', 'quantity', 'vwarehouse'), Fieldset('选填信息', 'memorandum'), Fieldset(None, 'creator', 'order_status', 'is_delete', 'distribution_order_id', 'error_tag', **{"style": "display:None"}), ] def queryset(self): queryset = super(UndistributionAdmin, self).queryset() queryset = queryset.filter(is_delete=0, order_status=1) return queryset def save_models(self): obj = self.new_obj request = self.request obj.creator = request.user.username obj.save() if not obj.distribution_order_id: prefix = "DO" serial_number = str(datetime.datetime.now()) serial_number = int( serial_number.replace("-", "").replace(" ", "").replace( ":", "").replace(".", "")) + i distribution_order_id = prefix + str(serial_number) + "A" obj.distribution_order_id = distribution_order_id obj.save() super().save_models()
def get_form_layout(self): """ 返回 Form Layout ,如果您设置了 :attr:`form_layout` 属性,则使用该属性,否则该方法会自动生成 Form Layout 。 有关 Form Layout 的更多信息可以参看 `Crispy Form 文档 <http://django-crispy-forms.readthedocs.org/en/latest/layouts.html>`_ 设置 Form Layout 可以非常灵活的显示表单页面的各个元素 """ layout = copy.deepcopy(self.form_layout) arr = self.form_obj.fields.keys() if six.PY3: arr = [k for k in arr] fields = arr + list(self.get_readonly_fields()) if layout is None: layout = Layout( Container( Col('full', Fieldset("", *fields, css_class="unsort no_title"), horizontal=True, span=12))) elif type(layout) in (list, tuple) and len(layout) > 0: # 如果设置的 layout 是一个列表,那么按以下方法生成 if isinstance(layout[0], Column): fs = layout elif isinstance(layout[0], (Fieldset, TabHolder)): fs = (Col('full', *layout, horizontal=True, span=12), ) else: fs = (Col('full', Fieldset("", *layout, css_class="unsort no_title"), horizontal=True, span=12), ) layout = Layout(Container(*fs)) rendered_fields = [i[1] for i in layout.get_field_names()] container = layout[0].fields other_fieldset = Fieldset( _(u'Other Fields'), *[f for f in fields if f not in rendered_fields]) # 将所有没有显示的字段和在一个 Fieldset 里面显示 if len(other_fieldset.fields): if len(container) and isinstance(container[0], Column): # 把其他字段放在第一列显示 container[0].fields.append(other_fieldset) else: container.append(other_fieldset) return layout
class WxRefundRecordAdmin(object): list_display = [ "return_code", "result_code", "appid", "mch_id", "out_trade_no", "out_refund_no", "refund_id", "refund_fee", "total_fee", 'return_msg' ] search_fields = [ 'out_trade_no', 'out_refund_no', 'refund_id', 'transaction_id' ] model_icon = 'fa fa-random' form_layout = (Fieldset( '微信退款日志', Row('return_code', 'return_msg'), Row('result_code', 'err_code'), Row('err_code_des', 'appid'), Row('mch_id', 'nonce_str'), Row('sign', 'transaction_id'), Row('out_trade_no', 'out_refund_no'), Row('refund_id', 'refund_fee'), Row('settlement_refund_fee', 'total_fee'), Row('settlement_total_fee', 'fee_type'), Row('cash_fee', 'cash_fee_type'), Row('cash_refund_fee'), ), ) def has_add_permission(self): return False def has_change_permission(self, obj=None): return False def has_delete_permission(self, obj=None): return False
class MemberAdmin(object): import_export_args = {'import_resource_class': MemberResource} fields = [field.name for field in Member._meta.fields] list_display = fields[1:8] search_fields = ['name'] list_filter = ['name'] model_icon = 'fa fa-info' list_per_page = 15 list_editable = list_display[1:] phases = dict() phases['基本信息'] = fields[:8] phases['阶段1:入党考察'] = fields[8:17] phases['阶段2:预备党员'] = fields[17:26] phases['阶段3:正式党员'] = fields[26:] wizard_form_list = phases.items() form_layout = (Main(*[Fieldset(k, *v) for k, v in wizard_form_list])) def get_readonly_fields(self): if not self.request.user.has_perm('info.add_member'): # 普通成员 return ['branch_name', 'netid'] + self.fields[8:] return [] def queryset(self): if not self.request.user.is_superuser: # 判断是否是超级用户 try: member = Member.objects.get(netid=self.request.user) if self.request.user.has_perm('info.add_member'): # 支书 return self.model.objects.filter(branch=member.branch) return self.model.objects.filter(netid=member.netid, branch=member.branch) # 普通成员 except: return self.model.objects.filter(netid="") return self.model.objects.all()
class BarCodeInfoAdmin(object): list_display = ['order_status', 'barcode', 'create_time', 'creator'] search_fields = ['barcode'] relfield_style = 'fk-ajax' form_layout = [ Fieldset('必填信息', 'barcode', 'order_status'), Fieldset(None, 'creator', 'is_delete', **{"style": "display:None"}), ] actions = [RejectSelectedAction] def save_models(self): obj = self.new_obj request = self.request obj.creator = request.user.username obj.save() super().save_models()
class TagAdmin(BaseOwnerAdmin): list_display = ('name', 'status', 'create_time') form_layout = (Fieldset('name', 'status'), ) def save_models(self): self.new_obj.owner = self.request.user return super().save_models()
class MusicAdmin(CommonSetting): list_display = ('name', 'is_active', 'author', 'mod', 'art_nums') search_fields = ('name', 'author') list_filter = ('is_active', ) readonly_fields = ('mod', ) ordering = ('pk', ) form_layout = ( Main( Fieldset( _("音乐信息"), Row('name', 'author'), Row('code'), Row('mod'), ), ), Side(Fieldset(_('状态'), 'is_active'), ), )
class CommentAdmin(BaseOwnerAdmin): list_display = [ "target", "nickname", "status", "email", "website", "created_time", "operator", ] fields = ( ("target", "status"), "content", "website", "email", ) form_layout = (Fieldset( Row('target', 'status'), 'content', 'website', 'email', ), ) exclude = ('author', ) def operator(self, obj): return format_html( '<a href="{}">编辑</a>', reverse("cus_admin:comment_comment_change", args=(obj.id, ))) # 不加简短描述,管理界面会显示operator operator.short_description = "操作"
class PostAdmin(BaseOwnerAdmin): form = PostAdminForm list_display = ['title', 'category', 'status', 'pv', 'uv', 'owner', 'created_time', 'operator'] list_filter = ['category', 'owner'] search_fields = ['title', 'category__name'] save_on_top = True actions_on_top = True actions_on_bottom = True exclude = ('html', 'owner', 'pv', 'uv') form_layout = ( Fieldset( '基础信息', 'title', 'desc', Row('category', 'status', 'is_markdown'), 'content', 'tags', ), ) def operator(self, obj): return format_html( '<a href={}>编辑</a>', reverse('cus_admin:blog_post_change', args=(obj.id,)) ) operator.allow_tags = True operator.short_description = '操作'
class SideBarAdmin(BaseOwnerAdmin): list_display = ['title', 'display_type', 'content', 'create_time', 'owner'] form_layout = (Fieldset('title', 'display_type', 'content'), ) def save_models(self): self.new_obj.owner = self.request.user return super().save_models()