From e3445b6a60b3ba23a30d86e16ab038cffac42b2d Mon Sep 17 00:00:00 2001 From: chirac Date: Sat, 2 Jan 2021 23:19:49 +0100 Subject: [PATCH] Move new autocomplete widgets on widget file --- cotisations/forms.py | 11 ++--- logs/forms.py | 4 +- machines/forms.py | 52 +++++++++++------------ multi_op/preferences/forms.py | 4 +- preferences/forms.py | 18 ++++---- re2o/mixins.py | 48 ---------------------- re2o/views.py | 3 -- re2o/widgets.py | 77 +++++++++++++++++++++++++++++++++++ tickets/forms.py | 5 ++- topologie/forms.py | 34 ++++++++-------- users/forms.py | 24 +++++------ 11 files changed, 154 insertions(+), 126 deletions(-) create mode 100644 re2o/widgets.py diff --git a/cotisations/forms.py b/cotisations/forms.py index 4689e3cb..f9e44686 100644 --- a/cotisations/forms.py +++ b/cotisations/forms.py @@ -45,11 +45,8 @@ from django.utils.translation import ugettext_lazy as _ from django.shortcuts import get_object_or_404 from re2o.field_permissions import FieldPermissionFormMixin -from re2o.mixins import ( - FormRevMixin, - AutocompleteModelMixin, - AutocompleteMultipleModelMixin, -) +from re2o.mixins import FormRevMixin +from re2o.widgets import AutocompleteModelWidget from .models import ( Article, Paiement, @@ -84,8 +81,8 @@ class FactureForm(FieldPermissionFormMixin, FormRevMixin, ModelForm): model = Facture fields = "__all__" widgets = { - "user": AutocompleteModelMixin(url="/users/user-autocomplete"), - "banque": AutocompleteModelMixin(url="/cotisations/banque-autocomplete"), + "user": AutocompleteModelWidget(url="/users/user-autocomplete"), + "banque": AutocompleteModelWidget(url="/cotisations/banque-autocomplete"), } def clean(self): diff --git a/logs/forms.py b/logs/forms.py index 03045e4a..0a2ca09c 100644 --- a/logs/forms.py +++ b/logs/forms.py @@ -25,7 +25,7 @@ from django import forms from django.forms import Form from django.utils.translation import ugettext_lazy as _ from re2o.base import get_input_formats_help_text -from re2o.mixins import AutocompleteModelMixin +from re2o.widgets import AutocompleteModelWidget import inspect @@ -114,7 +114,7 @@ class ActionsSearchForm(Form): label=_("Performed by"), queryset=users.models.User.objects.all(), required=False, - widget=AutocompleteModelMixin(url="/users/user-autocomplete"), + widget=AutocompleteModelWidget(url="/users/user-autocomplete"), ) action_type = forms.MultipleChoiceField( label=_("Action type"), diff --git a/machines/forms.py b/machines/forms.py index 9a563d9a..ed5975e3 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -40,10 +40,10 @@ from django.forms import ModelForm, Form from django.utils.translation import ugettext_lazy as _ from re2o.field_permissions import FieldPermissionFormMixin -from re2o.mixins import ( - FormRevMixin, - AutocompleteModelMixin, - AutocompleteMultipleModelMixin, +from re2o.mixins import FormRevMixin +from re2o.widgets import ( + AutocompleteModelWidget, + AutocompleteMultipleModelWidget, ) from .models import ( Domain, @@ -75,7 +75,7 @@ class EditMachineForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): class Meta: model = Machine fields = "__all__" - widgets = {"user": AutocompleteModelMixin(url="/users/user-autocomplete")} + widgets = {"user": AutocompleteModelWidget(url="/users/user-autocomplete")} def __init__(self, *args, **kwargs): prefix = kwargs.pop("prefix", self.Meta.model.__name__) @@ -97,11 +97,11 @@ class EditInterfaceForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): model = Interface fields = ["machine", "machine_type", "ipv4", "mac_address", "details"] widgets = { - "machine": AutocompleteModelMixin(url="/machines/machine-autocomplete"), - "machine_type": AutocompleteModelMixin( + "machine": AutocompleteModelWidget(url="/machines/machine-autocomplete"), + "machine_type": AutocompleteModelWidget( url="/machines/machinetype-autocomplete" ), - "ipv4": AutocompleteModelMixin( + "ipv4": AutocompleteModelWidget( url="/machines/iplist-autocomplete", forward=["machine_type"], attrs={ @@ -158,7 +158,7 @@ class AliasForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): model = Domain fields = ["name", "extension", "ttl"] widgets = { - "extension": AutocompleteModelMixin(url="/machines/extension-autocomplete") + "extension": AutocompleteModelWidget(url="/machines/extension-autocomplete") } def __init__(self, *args, **kwargs): @@ -210,7 +210,7 @@ class MachineTypeForm(FormRevMixin, ModelForm): model = MachineType fields = ["name", "ip_type"] widgets = { - "ip_type": AutocompleteModelMixin(url="/machines/iptype-autocomplete") + "ip_type": AutocompleteModelWidget(url="/machines/iptype-autocomplete") } def __init__(self, *args, **kwargs): @@ -247,9 +247,9 @@ class IpTypeForm(FormRevMixin, ModelForm): model = IpType fields = "__all__" widgets = { - "vlan": AutocompleteModelMixin(url="/machines/vlan-autocomplete"), - "extension": AutocompleteModelMixin(url="/machines/extension-autocomplete"), - "ouverture_ports": AutocompleteModelMixin( + "vlan": AutocompleteModelWidget(url="/machines/vlan-autocomplete"), + "extension": AutocompleteModelWidget(url="/machines/extension-autocomplete"), + "ouverture_ports": AutocompleteModelWidget( url="/machines/ouvertureportlist-autocomplete" ), } @@ -383,8 +383,8 @@ class MxForm(FormRevMixin, ModelForm): model = Mx fields = ["zone", "priority", "name", "ttl"] widgets = { - "zone": AutocompleteModelMixin(url="/machines/extension-autocomplete"), - "name": AutocompleteModelMixin(url="/machines/domain-autocomplete"), + "zone": AutocompleteModelWidget(url="/machines/extension-autocomplete"), + "name": AutocompleteModelWidget(url="/machines/domain-autocomplete"), } def __init__(self, *args, **kwargs): @@ -422,8 +422,8 @@ class NsForm(FormRevMixin, ModelForm): model = Ns fields = ["zone", "ns", "ttl"] widgets = { - "zone": AutocompleteModelMixin(url="/machines/extension-autocomplete"), - "ns": AutocompleteModelMixin(url="/machines/domain-autocomplete"), + "zone": AutocompleteModelWidget(url="/machines/extension-autocomplete"), + "ns": AutocompleteModelWidget(url="/machines/domain-autocomplete"), } def __init__(self, *args, **kwargs): @@ -459,7 +459,7 @@ class TxtForm(FormRevMixin, ModelForm): model = Txt fields = "__all__" widgets = { - "zone": AutocompleteModelMixin(url="/machines/extension-autocomplete") + "zone": AutocompleteModelWidget(url="/machines/extension-autocomplete") } def __init__(self, *args, **kwargs): @@ -492,7 +492,7 @@ class DNameForm(FormRevMixin, ModelForm): model = DName fields = "__all__" widgets = { - "zone": AutocompleteModelMixin(url="/machines/extension-autocomplete") + "zone": AutocompleteModelWidget(url="/machines/extension-autocomplete") } def __init__(self, *args, **kwargs): @@ -525,8 +525,8 @@ class SrvForm(FormRevMixin, ModelForm): model = Srv fields = "__all__" widgets = { - "extension": AutocompleteModelMixin(url="/machines/extension-autocomplete"), - "target": AutocompleteModelMixin(url="/machines/domain-autocomplete"), + "extension": AutocompleteModelWidget(url="/machines/extension-autocomplete"), + "target": AutocompleteModelWidget(url="/machines/domain-autocomplete"), } def __init__(self, *args, **kwargs): @@ -559,10 +559,10 @@ class NasForm(FormRevMixin, ModelForm): model = Nas fields = "__all__" widgets = { - "nas_type": AutocompleteModelMixin( + "nas_type": AutocompleteModelWidget( url="/machines/machinetype-autocomplete" ), - "machine_type": AutocompleteModelMixin( + "machine_type": AutocompleteModelWidget( url="/machines/machinetype-autocomplete" ), } @@ -597,7 +597,7 @@ class RoleForm(FormRevMixin, ModelForm): model = Role fields = "__all__" widgets = { - "servers": AutocompleteMultipleModelMixin( + "servers": AutocompleteMultipleModelWidget( url="/machines/interface-autocomplete" ) } @@ -635,7 +635,7 @@ class ServiceForm(FormRevMixin, ModelForm): model = Service fields = "__all__" widgets = { - "servers": AutocompleteMultipleModelMixin( + "servers": AutocompleteMultipleModelWidget( url="/machines/interface-autocomplete" ) } @@ -724,7 +724,7 @@ class EditOuverturePortConfigForm(FormRevMixin, ModelForm): model = Interface fields = ["port_lists"] widgets = { - "port_lists": AutocompleteMultipleModelMixin( + "port_lists": AutocompleteMultipleModelWidget( url="/machines/ouvertureportlist-autocomplete" ) } diff --git a/multi_op/preferences/forms.py b/multi_op/preferences/forms.py index 30aceb36..45941007 100644 --- a/multi_op/preferences/forms.py +++ b/multi_op/preferences/forms.py @@ -29,7 +29,7 @@ each. from django import forms from django.forms import ModelForm, Form from django.utils.translation import ugettext_lazy as _ -from re2o.mixins import AutocompleteMultipleModelMixin +from re2o.widgets import AutocompleteMultipleModelWidget from .models import MultiopOption @@ -41,7 +41,7 @@ class EditMultiopOptionForm(ModelForm): model = MultiopOption fields = "__all__" widgets = { - "enabled_dorm": AutocompleteMultipleModelMixin( + "enabled_dorm": AutocompleteMultipleModelWidget( url="/topologie/dormitory-autocomplete", ), } diff --git a/preferences/forms.py b/preferences/forms.py index a7d03162..e19737c1 100644 --- a/preferences/forms.py +++ b/preferences/forms.py @@ -29,7 +29,11 @@ from django.forms import ModelForm, Form from django.db.models import Q from django import forms from django.utils.translation import ugettext_lazy as _ -from re2o.mixins import FormRevMixin, AutocompleteModelMixin, AutocompleteMultipleModelMixin +from re2o.mixins import FormRevMixin +from re2o.widgets import ( + AutocompleteModelWidget, + AutocompleteMultipleModelWidget +) from .models import ( OptionalUser, OptionalMachine, @@ -110,14 +114,14 @@ class EditOptionalTopologieForm(ModelForm): automatic_provision_switchs = forms.ModelMultipleChoiceField( Switch.objects.all(), required=False, - widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"), + widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"), ) class Meta: model = OptionalTopologie fields = "__all__" widgets = { - "switchs_ip_type": AutocompleteModelMixin( + "switchs_ip_type": AutocompleteModelWidget( url="/machines/iptype-autocomplete", ), } @@ -176,7 +180,7 @@ class EditAssoOptionForm(ModelForm): model = AssoOption fields = "__all__" widgets = { - "utilisateur_asso": AutocompleteModelMixin( + "utilisateur_asso": AutocompleteModelWidget( url="/users/user-autocomplete", ), } @@ -267,7 +271,7 @@ class MandateForm(ModelForm): model = Mandate fields = "__all__" widgets = { - "president": AutocompleteModelMixin( + "president": AutocompleteModelWidget( url="/users/user-autocomplete", ), } @@ -387,7 +391,7 @@ class RadiusKeyForm(FormRevMixin, ModelForm): members = forms.ModelMultipleChoiceField( queryset=Switch.objects.all(), required=False, - widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"), + widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"), ) class Meta: @@ -413,7 +417,7 @@ class SwitchManagementCredForm(FormRevMixin, ModelForm): members = forms.ModelMultipleChoiceField( Switch.objects.all(), required=False, - widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"), + widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"), ) class Meta: diff --git a/re2o/mixins.py b/re2o/mixins.py index 471f7414..22933e67 100644 --- a/re2o/mixins.py +++ b/re2o/mixins.py @@ -26,7 +26,6 @@ A set of mixins used all over the project to avoid duplicating code from reversion import revisions as reversion from django.db import transaction from django.utils.translation import ugettext as _ -from dal import autocomplete class RevMixin(object): @@ -254,50 +253,3 @@ class AclMixin(object): (permission,), ) - -class AutocompleteModelMixin(autocomplete.ModelSelect2): - """ A mixin subclassing django-autocomplete-light's Select2 model to pass default options - See https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#passing-options-to-select2 - """ - - def __init__(self, *args, **kwargs): - select2_attrs = kwargs.get("attrs", {}) - kwargs["attrs"] = self.fill_default_select2_attrs(select2_attrs) - - super().__init__(*args, **kwargs) - - def fill_default_select2_attrs(self, attrs): - """ - See https://select2.org/configuration/options-api - """ - # Display the "x" button to clear the input by default - attrs["data-allow-clear"] = attrs.get("data-allow-clear", "true") - # If there are less than 10 results, just show all of them (no need to autocomplete) - attrs["data-minimum-results-for-search"] = attrs.get( - "data-minimum-results-for-search", 10 - ) - return attrs - - -class AutocompleteMultipleModelMixin(autocomplete.ModelSelect2Multiple): - """ A mixin subclassing django-autocomplete-light's Select2 model to pass default options - See https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#passing-options-to-select2 - """ - - def __init__(self, *args, **kwargs): - select2_attrs = kwargs.get("attrs", {}) - kwargs["attrs"] = self.fill_default_select2_attrs(select2_attrs) - - super().__init__(*args, **kwargs) - - def fill_default_select2_attrs(self, attrs): - """ - See https://select2.org/configuration/options-api - """ - # Display the "x" button to clear the input by default - attrs["data-allow-clear"] = attrs.get("data-allow-clear", "true") - # If there are less than 10 results, just show all of them (no need to autocomplete) - attrs["data-minimum-results-for-search"] = attrs.get( - "data-minimum-results-for-search", 10 - ) - return attrs diff --git a/re2o/views.py b/re2o/views.py index aa8ddc4b..ea22e97c 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -32,8 +32,6 @@ from django.shortcuts import render from django.template.context_processors import csrf from django.conf import settings from django.utils.translation import ugettext as _ -from django.views.decorators.cache import cache_page -from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin from django.utils.decorators import method_decorator from dal import autocomplete @@ -47,7 +45,6 @@ from preferences.models import ( Mandate, ) -from .acl import can_list from .contributors import CONTRIBUTORS from importlib import import_module from re2o.settings_local import OPTIONNAL_APPS_RE2O diff --git a/re2o/widgets.py b/re2o/widgets.py new file mode 100644 index 00000000..935806fe --- /dev/null +++ b/re2o/widgets.py @@ -0,0 +1,77 @@ +# -*- mode: python; coding: utf-8 -*- +# Re2o est un logiciel d'administration développé initiallement au Rézo Metz. Il +# se veut agnostique au réseau considéré, de manière à être installable en +# quelques clics. +# +# Copyright © 2021 Gabriel Détraz +# Copyright © 2021 Jean-Romain Garnier +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +""" +Re2o Forms and ModelForms Widgets. + +Used in others forms for using autocomplete engine. +""" + +from django.utils.translation import ugettext as _ +from dal import autocomplete + + +class AutocompleteModelWidget(autocomplete.ModelSelect2): + """ A mixin subclassing django-autocomplete-light's Select2 model to pass default options + See https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#passing-options-to-select2 + """ + + def __init__(self, *args, **kwargs): + select2_attrs = kwargs.get("attrs", {}) + kwargs["attrs"] = self.fill_default_select2_attrs(select2_attrs) + + super().__init__(*args, **kwargs) + + def fill_default_select2_attrs(self, attrs): + """ + See https://select2.org/configuration/options-api + """ + # Display the "x" button to clear the input by default + attrs["data-allow-clear"] = attrs.get("data-allow-clear", "true") + # If there are less than 10 results, just show all of them (no need to autocomplete) + attrs["data-minimum-results-for-search"] = attrs.get( + "data-minimum-results-for-search", 10 + ) + return attrs + + +class AutocompleteMultipleModelWidget(autocomplete.ModelSelect2Multiple): + """ A mixin subclassing django-autocomplete-light's Select2 model to pass default options + See https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#passing-options-to-select2 + """ + + def __init__(self, *args, **kwargs): + select2_attrs = kwargs.get("attrs", {}) + kwargs["attrs"] = self.fill_default_select2_attrs(select2_attrs) + + super().__init__(*args, **kwargs) + + def fill_default_select2_attrs(self, attrs): + """ + See https://select2.org/configuration/options-api + """ + # Display the "x" button to clear the input by default + attrs["data-allow-clear"] = attrs.get("data-allow-clear", "true") + # If there are less than 10 results, just show all of them (no need to autocomplete) + attrs["data-minimum-results-for-search"] = attrs.get( + "data-minimum-results-for-search", 10 + ) + return attrs diff --git a/tickets/forms.py b/tickets/forms.py index ecde5492..aad78837 100644 --- a/tickets/forms.py +++ b/tickets/forms.py @@ -28,7 +28,8 @@ from django import forms from django.template.loader import render_to_string from django.forms import ModelForm, Form from re2o.field_permissions import FieldPermissionFormMixin -from re2o.mixins import FormRevMixin, AutocompleteModelMixin, AutocompleteMultipleModelMixin +from re2o.mixins import FormRevMixin +from re2o.widgets import AutocompleteModelWidget from django.utils.translation import ugettext_lazy as _ from .models import Ticket, CommentTicket @@ -59,7 +60,7 @@ class EditTicketForm(FormRevMixin, ModelForm): model = Ticket fields = "__all__" widgets = { - "user": AutocompleteModelMixin( + "user": AutocompleteModelWidget( url="/users/user-autocomplete", ), } diff --git a/topologie/forms.py b/topologie/forms.py index e88218fd..300253f6 100644 --- a/topologie/forms.py +++ b/topologie/forms.py @@ -37,10 +37,10 @@ from django.utils.translation import ugettext_lazy as _ from machines.models import Interface from machines.forms import EditMachineForm, NewMachineForm -from re2o.mixins import ( - FormRevMixin, - AutocompleteModelMixin, - AutocompleteMultipleModelMixin, +from re2o.mixins import FormRevMixin +from re2o.widgets import ( + AutocompleteModelWidget, + AutocompleteMultipleModelWidget, ) from .models import ( @@ -67,13 +67,13 @@ class PortForm(FormRevMixin, ModelForm): model = Port fields = "__all__" widgets = { - "switch": AutocompleteModelMixin(url="/topologie/switch-autocomplete"), - "room": AutocompleteModelMixin(url="/topologie/room-autocomplete"), - "machine_interface": AutocompleteModelMixin( + "switch": AutocompleteModelWidget(url="/topologie/switch-autocomplete"), + "room": AutocompleteModelWidget(url="/topologie/room-autocomplete"), + "machine_interface": AutocompleteModelWidget( url="/machine/machine-autocomplete" ), - "related": AutocompleteModelMixin(url="/topologie/port-autocomplete"), - "custom_profile": AutocompleteModelMixin( + "related": AutocompleteModelWidget(url="/topologie/port-autocomplete"), + "custom_profile": AutocompleteModelWidget( url="/topologie/portprofile-autocomplete" ), } @@ -181,10 +181,10 @@ class EditSwitchForm(EditMachineForm): model = Switch fields = "__all__" widgets = { - "switchbay": AutocompleteModelMixin( + "switchbay": AutocompleteModelWidget( url="/topologie/switchbay-autocomplete" ), - "user": AutocompleteModelMixin(url="/users/user-autocomplete"), + "user": AutocompleteModelWidget(url="/users/user-autocomplete"), } @@ -202,7 +202,7 @@ class EditRoomForm(FormRevMixin, ModelForm): model = Room fields = "__all__" widgets = { - "building": AutocompleteModelMixin(url="/topologie/building-autocomplete") + "building": AutocompleteModelWidget(url="/topologie/building-autocomplete") } def __init__(self, *args, **kwargs): @@ -222,7 +222,7 @@ class EditModelSwitchForm(FormRevMixin, ModelForm): members = forms.ModelMultipleChoiceField( Switch.objects.all(), - widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"), + widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"), required=False, ) @@ -261,14 +261,14 @@ class EditSwitchBayForm(FormRevMixin, ModelForm): members = forms.ModelMultipleChoiceField( Switch.objects.all(), required=False, - widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"), + widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"), ) class Meta: model = SwitchBay fields = "__all__" widgets = { - "building": AutocompleteModelMixin(url="/topologie/building-autocomplete") + "building": AutocompleteModelWidget(url="/topologie/building-autocomplete") } def __init__(self, *args, **kwargs): @@ -315,10 +315,10 @@ class EditPortProfileForm(FormRevMixin, ModelForm): model = PortProfile fields = "__all__" widgets = { - "vlan_tagged": AutocompleteMultipleModelMixin( + "vlan_tagged": AutocompleteMultipleModelWidget( url="/machines/vlan-autocomplete" ), - "vlan_untagged": AutocompleteModelMixin(url="/machines/vlan-autocomplete"), + "vlan_untagged": AutocompleteModelWidget(url="/machines/vlan-autocomplete"), } def __init__(self, *args, **kwargs): diff --git a/users/forms.py b/users/forms.py index dbe1cf7e..172a8c54 100644 --- a/users/forms.py +++ b/users/forms.py @@ -63,10 +63,10 @@ from topologie.models import Port from preferences.models import OptionalUser from re2o.utils import remove_user_room from re2o.base import get_input_formats_help_text -from re2o.mixins import ( - FormRevMixin, - AutocompleteMultipleModelMixin, - AutocompleteModelMixin, +from re2o.mixins import FormRevMixin +from re2o.widgets import ( + AutocompleteMultipleModelWidget, + AutocompleteModelWidget, ) from re2o.field_permissions import FieldPermissionFormMixin @@ -351,14 +351,14 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): "room", ] widgets = { - "school": AutocompleteModelMixin(url="/users/school-autocomplete"), - "room": AutocompleteModelMixin( + "school": AutocompleteModelWidget(url="/users/school-autocomplete"), + "room": AutocompleteModelWidget( url="/topologie/room-autocomplete", attrs={ "data-minimum-input-length": 3 # Only trigger autocompletion after 3 characters have been typed }, ), - "shell": AutocompleteModelMixin(url="/users/shell-autocomplete"), + "shell": AutocompleteModelWidget(url="/users/shell-autocomplete"), } force = forms.BooleanField( @@ -623,9 +623,9 @@ class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): "mailing", ] widgets = { - "school": AutocompleteModelMixin(url="/users/school-autocomplete"), - "room": AutocompleteModelMixin(url="/topologie/room-autocomplete"), - "shell": AutocompleteModelMixin(url="/users/shell-autocomplete"), + "school": AutocompleteModelWidget(url="/users/school-autocomplete"), + "room": AutocompleteModelWidget(url="/topologie/room-autocomplete"), + "shell": AutocompleteModelWidget(url="/users/shell-autocomplete"), } def clean_telephone(self): @@ -656,10 +656,10 @@ class ClubAdminandMembersForm(FormRevMixin, ModelForm): model = Club fields = ["administrators", "members"] widgets = { - "administrators": AutocompleteMultipleModelMixin( + "administrators": AutocompleteMultipleModelWidget( url="/users/adherent-autocomplete" ), - "members": AutocompleteMultipleModelMixin( + "members": AutocompleteMultipleModelWidget( url="/users/adherent-autocomplete" ), }