Django xadmin custom widget plug-in (display style of custom detail page fields)

Keywords: Python Django JQuery Database

Sometimes we want to modify the display mode of xadmin detail page fields. For example, django's default ImageField displays the image url in the background, and we prefer to see the image thumbnail. For example, django displays many to many fields as a drop-down box or a left and right selection column, showing the two kinds of fields to the image:

 

 

 

 

 

 

 

What do I do if I want the above search only one line effect?

This requires us to customize the widget plug-in.

So what is a widget plug-in?

When django admin renders the form form, it will render the field into different display effects according to the type of the field (ImageField, DateTtimeField, TextField, etc.), so where to specify these display effects, you need widget plug-ins. Each field type in django corresponds to a plug-in, which specifies the font size and color layout. Plug in is essentially a class. django xadmin plug-in is located in xadmin\widgets.py file.

 

Next, take many to many fields as an example to introduce the custom widget method.

Define widget:
xadmin\widgets.py

You can use self.attrs to get the previously passed request related parameters

class M2MFilterWidget(forms.SelectMultiple):
 
    # The media method is to import the js and css files you need
    @property
    def media(self): 
        # There are four files in total: bootstrap.min.css jquery-1.11.0.min.js selectpage.css selectpage.js. The first two systems have been loaded, only the last two need to be loaded
        return vendor('xadmin.widget.selectpage.js', 'xadmin.widget.selectpage.css')
    
    # The render method is to render the style of the field you want to display, usually returning the html string
    def render(self, name, value, attrs=None):
        # Display the selected values in the database to the page. To convert the value ([1,3,5,8...] list format) to value_str ('1,3,5,8' string format)
        value_str = ','.join(map(str, value)) if value else ''
        
        # You can use self.attrs to get the previously passed request related parameters
        attrs = self.attrs
            
        # Get all optional options of many to many fields and pass them to the front end for search filtering
        choices = self.choices.field._queryset
        # Fixed choices data format
        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="Please enter query keywords">'
                             '</div>'
                         '</div>'
                         %(name, choices_data, name, name, value_str))

  

Be careful:

The file name of the imported js css must be xadmin.widget.xxx.js and xadmin.widget.xxx.css, and it should be placed under xadmin/static/js and xadmin/static/css. I will not expand the specific reasons. If you are interested, you can trace the function verdor.

In addition, if your requirements are the same as this example, 'xadmin. Widget. Selectpage. JS' and' xadmin. Widget. Selectpage. CSS' can be commented or sent to me. You can also download it here

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

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

 

Use a custom widget:
1. To use it on the details page, set it in adminx.py

adminx.py

#Kwargs ['widget '] = m2mfilterwidget (attrs = {' input'type ':'hidden','user'id ': self. Request. User. ID}) is written to pass some parameters of the current request to the widget. Because the request related parameters cannot be obtained in the widget.

m2mfilter_list = ['interviewer_1', 'interviewer_2', 'interviewer_3']
 
    # Specify widget for all ManyToManyField fields of the current model
    # formfield_overrides = {models.ManyToManyField: {'widget': M2MFilterWidget}}  
    
    #Assign a widget to a Field field in the current model
    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)

When it is finished, you can see the display mode of many to many fields by opening the browser as follows:

 

 

2. Use in custom form

class BulkEditForm(forms.ModelForm):
    class Meta:
        model = HrUser
        fields = ['username', 'owner']
 
        widgets = {
            'owner': M2MFilterWidget,
        }
 
class BulkEditAction(BaseActionView):
    action_name = "bulk_edit_action"
    description = 'Modify selected resume owner'
    model_perm = 'change'
    
    # Here you need to override the media method to load static files
    @property
    def media(self):
        return vendor('xadmin.widget.selectpage.js', 'xadmin.widget.selectpage.css')
 
    def do_action(self, queryset):
        title = 'Please select resume owner'
        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('resume:' + 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)

 

 

 

If you want to display the ImageField as a picture thumbnail instead of a picture address, please read this article

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


Original link: https://blog.csdn.net/bocai xiaodaidai/article/details/95172133

Posted by ben2468 on Sun, 15 Dec 2019 05:51:41 -0800