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