django-xadmin custom widget plug-ins (custom display style details page field)

Sometimes we want to change the display mode xadmin details page field, such as django default ImageField displayed in the background is the image url, we would like to see a thumbnail image; another example django many-field will be displayed as multiple choice the drop-down box to select columns or about the way the picture shows these two:

 

 

 

 

 

 

 

If I want to bring this above search results and only one line going to help them?

This requires us to customize the widget plugin.

So what is a widget plug it?

django admin form when rendering the form, according to the type of field (ImageField, DateTtimeField, TextField, etc.) will be rendered into different fields of display of results, then the provisions of those shows where the effects of it, you need a widget plug, django of each an insert will correspond to field type, font size predetermined color plug arrangement methods. Plug-in is essentially a class, django-xadmin plug located xadmin \ widgets.py file.

 

Here's to many to many fields as an example, a custom widget methods.

Define the widget:
xadmin \ widgets.py

May request the relevant parameters passed before the acquisition by self.attrs

class M2MFilterWidget(forms.SelectMultiple):
 
    # media方法是引入你所需要的js、css文件
    @property
    def media(self): 
        # 共四个文件:bootstrap.min.css  jquery-1.11.0.min.js  selectpage.css selectpage.js,前两个系统已经加载,只需再加载后两个
        return vendor('xadmin.widget.selectpage.js', 'xadmin.widget.selectpage.css')
    
    # render方法是渲染你要展示字段的样式,通常返回html字符串
    def render(self, name, value, attrs=None):
        # 将数据库中已经被选中的值展示到页面,要将value([1,3,5,8...]列表格式)转化为value_str(‘1,3,5,8’字符串格式)
        value_str = ','.join(map(str, value)) if value else ''
        
        # 可以用self.attrs获取之前传递的request相关的参数
        attrs = self.attrs
            
        # 获取多对多字段的所有可选选项传递到前端,以便前端进行搜索过滤
        choices = self.choices.field._queryset
        # choices_data格式固定
        choices_data = [{'id': choice.id, 'name': choice.username} for choice in choices]
        return mark_safe('<div >'
                             '<div class="m2mfilter" id="m2m_%s" style="display: none">%s</div>'
                             '<div class="col-md-12">'
                                '<input type="text" id="selectPage_%s" class="form-control" name="%s" value=%s placeholder="请输入查询关键字">'
                             '</div>'
                         '</div>'
                         %(name, choices_data, name, name, value_str))

  

注意:

引入的js css文件名必须是xadmin.widget.xxx.js、xadmin.widget.xxx.css格式,而且要放在xadmin/static/js、xadmin/static/css下面,具体原因我就不展开讲了,有兴趣你可以追踪下verdor这个函数里面就知道了。

另外如果你的需求和本例一样,'xadmin.widget.selectpage.js', 'xadmin.widget.selectpage.css'这两个文件可以评论或者私信和我要。也可以在这里下载

https://download.csdn.net/download/bocai_xiaodaidai/11422561

https://download.csdn.net/download/bocai_xiaodaidai/11422556

 

使用自定义的widget:
1、在详情页使用,要在adminx.py中设置

adminx.py

#kwargs['widget'] = M2MFilterWidget(attrs={'input_type': 'hidden', 'user_id':self.request.user.id})这种写法的作用是可以将当前请求的某些参数传递到widget中。因为在widget中是无法获取request相关参数的。

m2mfilter_list = ['interviewer_1', 'interviewer_2', 'interviewer_3']
 
    # 给当前模型所有ManyToManyField字段指定widget
    # formfield_overrides = {models.ManyToManyField: {'widget': M2MFilterWidget}}  
    
    #给当前模型某个Field字段指定widget
    def formfield_for_dbfield(self, db_field, **kwargs):   
        if db_field.name in self.m2mfilter_list:
            kwargs['widget'] = M2MFilterWidget
            #kwargs['widget'] = M2MFilterWidget(attrs={'input_type': 'hidden', 'user_id':self.request.user.id})
            return db_field.formfield(**kwargs)
        return super().formfield_for_dbfield(db_field, **kwargs)

大功告成,打开浏览器就可以看到这个多对多字段的显示方式为下面这样了:

 

 

2、在自定义表单中使用

class BulkEditForm(forms.ModelForm):
    class Meta:
        model = HrUser
        fields = ['username', 'owner']
 
        widgets = {
            'owner': M2MFilterWidget,
        }
 
class BulkEditAction(BaseActionView):
    action_name = "bulk_edit_action"
    description = '修改所选简历 所有者'
    model_perm = 'change'
    
    # 这里要重写media方法加载静态文件
    @property
    def media(self):
        return vendor('xadmin.widget.selectpage.js', 'xadmin.widget.selectpage.css')
 
    def do_action(self, queryset):
        title = '请选择简历 所有者'
        form = BulkEditForm()
        hruser_projected = []
        username_list = []
        for obj in queryset:
            username_list.append(obj.username)
            if not is_group_member(self.request, settings.CONSTANTS['MANAGER_GROUP_NAME']):
                hruser_projected.append('简历:' + obj.username)
 
        context = self.get_context()
        context.update({
            "title": title,
            'queryset': queryset,
            'usernames': ','.join(username_list),
            'form': form,
            "hruser_projected": hruser_projected,
            "opts": self.opts,
            "app_label": self.app_label,
        })
        return TemplateResponse(self.request,'xadmin/bulk_edit.html', context)

 

 

 

如果你想将ImageField字段显示为图片缩略图而非图片地址,可以看下我的这篇文章

https://blog.csdn.net/bocai_xiaodaidai/article/details/95179098


原文链接:https://blog.csdn.net/bocai_xiaodaidai/article/details/95172133

Guess you like

Origin www.cnblogs.com/zmdComeOn/p/12045902.html