Django: replacing the standard ManyToMany forms widget

I know whom to replace ManyToMany Widget in django admin interface:

class SomeModelAdmin(admin.ModelAdmin): filter_horizontal = ('users',) 

But how to replace the default widget in all views?

I assume this can be implemented without changing a single line in my code or in django.

It would be great if I could something like the Author part (two blocks for ManyToMany input) in this figure using a widget:

enter image description here

I can use ctrl + click, but my users cannot. They need an easier way.

Is there a way to replace all select-multiple widgets without many changes in my code?

+6
source share
3 answers

If I do not understand your question, check in the comments.

The Django Form Widgets documentation offers several predefined widgets that you can use to indicate how the field is displayed in your form.

Without changing the code in my views, I can simply add the widget keyword to the appropriate form fields.

forms.py (v1)

 class TestForm(forms.Form): CHOICES = ( (1, "choice1"), (2, "choice2"), (3, "choice3"), ) field = forms.ChoiceField(choices=CHOICES) 

Select is displayed as a drop-down list:

 <select id="id_field" name="field"> <option value="1">choice1</option> <option value="2">choice2</option> <option value="3">choice3</option> </select> 

Now add the widget keyword to my field:

forms.py (v2)

 field = forms.ChoiceField(choices=CHOICES, widget=forms.CheckboxSelectMultiple) 

This displays a list of checkboxes:

 <ul id="id_field"> <li> <label for="id_field_0"><input id="id_field_0" name="field" type="checkbox" value="1" /> choice1</label> </li> <li> <label for="id_field_1"><input id="id_field_1" name="field" type="checkbox" value="2" /> choice2</label> </li> <li> <label for="id_field_2"><input id="id_field_2" name="field" type="checkbox" value="3" /> choice3</label> </li> </ul> 

Edit

You can also add widgets that are used by the Django administrator. See the Django multi-user widget for more details ? . Just import the corresponding widget:

 from django.contrib.admin.widgets import FilteredSelectMultiple 

and use it instead. Please note that in this particular case, you will also need to include the media form in order to get the desired effect.

+4
source

You can use a base class that is ovride formfield_for_manytomany

 from django.contrib.admin import widgets class ManyToManyAdmin(admin.ModelAdmin): def formfield_for_manytomany(self, db_field, request=None, **kwargs): kwargs['widget']= widgets.FilteredSelectMultiple( db_field.verbose_name, db_field.name in self.filter_vertical ) return super(admin.ModelAdmin, self).formfield_for_manytomany( db_field, request=request, **kwargs) class SomeModelAdmin(ManyToManyAdmin): pass 
+3
source

You need to replace the default widgets in django formats.

This works for me:

  from django import forms from django.contrib.admin.widgets import FilteredSelectMultiple # replace MultipleChoise in Forms forms.MultipleChoiceField.widget = FilteredSelectMultiple("verbose name", is_stacked=False) # replace MultipleChoise in ModelForms forms.ModelMultipleChoiceField.widget = FilteredSelectMultiple("verbose name", is_stacked=False) 
  • Add the code above to the forms_setup.py file in your main project
  • Then in settings.py import the forms_setup.py file:

     from .forms_setup import * 
+1
source

All Articles