mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-21 19:03:11 +00:00
Move new autocomplete widgets on widget file
This commit is contained in:
parent
8beece200d
commit
e3445b6a60
11 changed files with 154 additions and 126 deletions
|
@ -45,11 +45,8 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
from re2o.field_permissions import FieldPermissionFormMixin
|
from re2o.field_permissions import FieldPermissionFormMixin
|
||||||
from re2o.mixins import (
|
from re2o.mixins import FormRevMixin
|
||||||
FormRevMixin,
|
from re2o.widgets import AutocompleteModelWidget
|
||||||
AutocompleteModelMixin,
|
|
||||||
AutocompleteMultipleModelMixin,
|
|
||||||
)
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Article,
|
Article,
|
||||||
Paiement,
|
Paiement,
|
||||||
|
@ -84,8 +81,8 @@ class FactureForm(FieldPermissionFormMixin, FormRevMixin, ModelForm):
|
||||||
model = Facture
|
model = Facture
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"user": AutocompleteModelMixin(url="/users/user-autocomplete"),
|
"user": AutocompleteModelWidget(url="/users/user-autocomplete"),
|
||||||
"banque": AutocompleteModelMixin(url="/cotisations/banque-autocomplete"),
|
"banque": AutocompleteModelWidget(url="/cotisations/banque-autocomplete"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
|
|
@ -25,7 +25,7 @@ from django import forms
|
||||||
from django.forms import Form
|
from django.forms import Form
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from re2o.base import get_input_formats_help_text
|
from re2o.base import get_input_formats_help_text
|
||||||
from re2o.mixins import AutocompleteModelMixin
|
from re2o.widgets import AutocompleteModelWidget
|
||||||
|
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ class ActionsSearchForm(Form):
|
||||||
label=_("Performed by"),
|
label=_("Performed by"),
|
||||||
queryset=users.models.User.objects.all(),
|
queryset=users.models.User.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
widget=AutocompleteModelMixin(url="/users/user-autocomplete"),
|
widget=AutocompleteModelWidget(url="/users/user-autocomplete"),
|
||||||
)
|
)
|
||||||
action_type = forms.MultipleChoiceField(
|
action_type = forms.MultipleChoiceField(
|
||||||
label=_("Action type"),
|
label=_("Action type"),
|
||||||
|
|
|
@ -40,10 +40,10 @@ from django.forms import ModelForm, Form
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from re2o.field_permissions import FieldPermissionFormMixin
|
from re2o.field_permissions import FieldPermissionFormMixin
|
||||||
from re2o.mixins import (
|
from re2o.mixins import FormRevMixin
|
||||||
FormRevMixin,
|
from re2o.widgets import (
|
||||||
AutocompleteModelMixin,
|
AutocompleteModelWidget,
|
||||||
AutocompleteMultipleModelMixin,
|
AutocompleteMultipleModelWidget,
|
||||||
)
|
)
|
||||||
from .models import (
|
from .models import (
|
||||||
Domain,
|
Domain,
|
||||||
|
@ -75,7 +75,7 @@ class EditMachineForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Machine
|
model = Machine
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {"user": AutocompleteModelMixin(url="/users/user-autocomplete")}
|
widgets = {"user": AutocompleteModelWidget(url="/users/user-autocomplete")}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
prefix = kwargs.pop("prefix", self.Meta.model.__name__)
|
||||||
|
@ -97,11 +97,11 @@ class EditInterfaceForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = ["machine", "machine_type", "ipv4", "mac_address", "details"]
|
fields = ["machine", "machine_type", "ipv4", "mac_address", "details"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"machine": AutocompleteModelMixin(url="/machines/machine-autocomplete"),
|
"machine": AutocompleteModelWidget(url="/machines/machine-autocomplete"),
|
||||||
"machine_type": AutocompleteModelMixin(
|
"machine_type": AutocompleteModelWidget(
|
||||||
url="/machines/machinetype-autocomplete"
|
url="/machines/machinetype-autocomplete"
|
||||||
),
|
),
|
||||||
"ipv4": AutocompleteModelMixin(
|
"ipv4": AutocompleteModelWidget(
|
||||||
url="/machines/iplist-autocomplete",
|
url="/machines/iplist-autocomplete",
|
||||||
forward=["machine_type"],
|
forward=["machine_type"],
|
||||||
attrs={
|
attrs={
|
||||||
|
@ -158,7 +158,7 @@ class AliasForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
model = Domain
|
model = Domain
|
||||||
fields = ["name", "extension", "ttl"]
|
fields = ["name", "extension", "ttl"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"extension": AutocompleteModelMixin(url="/machines/extension-autocomplete")
|
"extension": AutocompleteModelWidget(url="/machines/extension-autocomplete")
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -210,7 +210,7 @@ class MachineTypeForm(FormRevMixin, ModelForm):
|
||||||
model = MachineType
|
model = MachineType
|
||||||
fields = ["name", "ip_type"]
|
fields = ["name", "ip_type"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"ip_type": AutocompleteModelMixin(url="/machines/iptype-autocomplete")
|
"ip_type": AutocompleteModelWidget(url="/machines/iptype-autocomplete")
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -247,9 +247,9 @@ class IpTypeForm(FormRevMixin, ModelForm):
|
||||||
model = IpType
|
model = IpType
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"vlan": AutocompleteModelMixin(url="/machines/vlan-autocomplete"),
|
"vlan": AutocompleteModelWidget(url="/machines/vlan-autocomplete"),
|
||||||
"extension": AutocompleteModelMixin(url="/machines/extension-autocomplete"),
|
"extension": AutocompleteModelWidget(url="/machines/extension-autocomplete"),
|
||||||
"ouverture_ports": AutocompleteModelMixin(
|
"ouverture_ports": AutocompleteModelWidget(
|
||||||
url="/machines/ouvertureportlist-autocomplete"
|
url="/machines/ouvertureportlist-autocomplete"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -383,8 +383,8 @@ class MxForm(FormRevMixin, ModelForm):
|
||||||
model = Mx
|
model = Mx
|
||||||
fields = ["zone", "priority", "name", "ttl"]
|
fields = ["zone", "priority", "name", "ttl"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"zone": AutocompleteModelMixin(url="/machines/extension-autocomplete"),
|
"zone": AutocompleteModelWidget(url="/machines/extension-autocomplete"),
|
||||||
"name": AutocompleteModelMixin(url="/machines/domain-autocomplete"),
|
"name": AutocompleteModelWidget(url="/machines/domain-autocomplete"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -422,8 +422,8 @@ class NsForm(FormRevMixin, ModelForm):
|
||||||
model = Ns
|
model = Ns
|
||||||
fields = ["zone", "ns", "ttl"]
|
fields = ["zone", "ns", "ttl"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"zone": AutocompleteModelMixin(url="/machines/extension-autocomplete"),
|
"zone": AutocompleteModelWidget(url="/machines/extension-autocomplete"),
|
||||||
"ns": AutocompleteModelMixin(url="/machines/domain-autocomplete"),
|
"ns": AutocompleteModelWidget(url="/machines/domain-autocomplete"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -459,7 +459,7 @@ class TxtForm(FormRevMixin, ModelForm):
|
||||||
model = Txt
|
model = Txt
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"zone": AutocompleteModelMixin(url="/machines/extension-autocomplete")
|
"zone": AutocompleteModelWidget(url="/machines/extension-autocomplete")
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -492,7 +492,7 @@ class DNameForm(FormRevMixin, ModelForm):
|
||||||
model = DName
|
model = DName
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"zone": AutocompleteModelMixin(url="/machines/extension-autocomplete")
|
"zone": AutocompleteModelWidget(url="/machines/extension-autocomplete")
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -525,8 +525,8 @@ class SrvForm(FormRevMixin, ModelForm):
|
||||||
model = Srv
|
model = Srv
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"extension": AutocompleteModelMixin(url="/machines/extension-autocomplete"),
|
"extension": AutocompleteModelWidget(url="/machines/extension-autocomplete"),
|
||||||
"target": AutocompleteModelMixin(url="/machines/domain-autocomplete"),
|
"target": AutocompleteModelWidget(url="/machines/domain-autocomplete"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -559,10 +559,10 @@ class NasForm(FormRevMixin, ModelForm):
|
||||||
model = Nas
|
model = Nas
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"nas_type": AutocompleteModelMixin(
|
"nas_type": AutocompleteModelWidget(
|
||||||
url="/machines/machinetype-autocomplete"
|
url="/machines/machinetype-autocomplete"
|
||||||
),
|
),
|
||||||
"machine_type": AutocompleteModelMixin(
|
"machine_type": AutocompleteModelWidget(
|
||||||
url="/machines/machinetype-autocomplete"
|
url="/machines/machinetype-autocomplete"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -597,7 +597,7 @@ class RoleForm(FormRevMixin, ModelForm):
|
||||||
model = Role
|
model = Role
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"servers": AutocompleteMultipleModelMixin(
|
"servers": AutocompleteMultipleModelWidget(
|
||||||
url="/machines/interface-autocomplete"
|
url="/machines/interface-autocomplete"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -635,7 +635,7 @@ class ServiceForm(FormRevMixin, ModelForm):
|
||||||
model = Service
|
model = Service
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"servers": AutocompleteMultipleModelMixin(
|
"servers": AutocompleteMultipleModelWidget(
|
||||||
url="/machines/interface-autocomplete"
|
url="/machines/interface-autocomplete"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -724,7 +724,7 @@ class EditOuverturePortConfigForm(FormRevMixin, ModelForm):
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = ["port_lists"]
|
fields = ["port_lists"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"port_lists": AutocompleteMultipleModelMixin(
|
"port_lists": AutocompleteMultipleModelWidget(
|
||||||
url="/machines/ouvertureportlist-autocomplete"
|
url="/machines/ouvertureportlist-autocomplete"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ each.
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.forms import ModelForm, Form
|
from django.forms import ModelForm, Form
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from re2o.mixins import AutocompleteMultipleModelMixin
|
from re2o.widgets import AutocompleteMultipleModelWidget
|
||||||
|
|
||||||
from .models import MultiopOption
|
from .models import MultiopOption
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ class EditMultiopOptionForm(ModelForm):
|
||||||
model = MultiopOption
|
model = MultiopOption
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"enabled_dorm": AutocompleteMultipleModelMixin(
|
"enabled_dorm": AutocompleteMultipleModelWidget(
|
||||||
url="/topologie/dormitory-autocomplete",
|
url="/topologie/dormitory-autocomplete",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,11 @@ from django.forms import ModelForm, Form
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext_lazy as _
|
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 (
|
from .models import (
|
||||||
OptionalUser,
|
OptionalUser,
|
||||||
OptionalMachine,
|
OptionalMachine,
|
||||||
|
@ -110,14 +114,14 @@ class EditOptionalTopologieForm(ModelForm):
|
||||||
automatic_provision_switchs = forms.ModelMultipleChoiceField(
|
automatic_provision_switchs = forms.ModelMultipleChoiceField(
|
||||||
Switch.objects.all(),
|
Switch.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"),
|
widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OptionalTopologie
|
model = OptionalTopologie
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"switchs_ip_type": AutocompleteModelMixin(
|
"switchs_ip_type": AutocompleteModelWidget(
|
||||||
url="/machines/iptype-autocomplete",
|
url="/machines/iptype-autocomplete",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -176,7 +180,7 @@ class EditAssoOptionForm(ModelForm):
|
||||||
model = AssoOption
|
model = AssoOption
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"utilisateur_asso": AutocompleteModelMixin(
|
"utilisateur_asso": AutocompleteModelWidget(
|
||||||
url="/users/user-autocomplete",
|
url="/users/user-autocomplete",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -267,7 +271,7 @@ class MandateForm(ModelForm):
|
||||||
model = Mandate
|
model = Mandate
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"president": AutocompleteModelMixin(
|
"president": AutocompleteModelWidget(
|
||||||
url="/users/user-autocomplete",
|
url="/users/user-autocomplete",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -387,7 +391,7 @@ class RadiusKeyForm(FormRevMixin, ModelForm):
|
||||||
members = forms.ModelMultipleChoiceField(
|
members = forms.ModelMultipleChoiceField(
|
||||||
queryset=Switch.objects.all(),
|
queryset=Switch.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"),
|
widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -413,7 +417,7 @@ class SwitchManagementCredForm(FormRevMixin, ModelForm):
|
||||||
members = forms.ModelMultipleChoiceField(
|
members = forms.ModelMultipleChoiceField(
|
||||||
Switch.objects.all(),
|
Switch.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"),
|
widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -26,7 +26,6 @@ A set of mixins used all over the project to avoid duplicating code
|
||||||
from reversion import revisions as reversion
|
from reversion import revisions as reversion
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from dal import autocomplete
|
|
||||||
|
|
||||||
|
|
||||||
class RevMixin(object):
|
class RevMixin(object):
|
||||||
|
@ -254,50 +253,3 @@ class AclMixin(object):
|
||||||
(permission,),
|
(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
|
|
||||||
|
|
|
@ -32,8 +32,6 @@ from django.shortcuts import render
|
||||||
from django.template.context_processors import csrf
|
from django.template.context_processors import csrf
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext as _
|
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.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from dal import autocomplete
|
from dal import autocomplete
|
||||||
|
@ -47,7 +45,6 @@ from preferences.models import (
|
||||||
Mandate,
|
Mandate,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .acl import can_list
|
|
||||||
from .contributors import CONTRIBUTORS
|
from .contributors import CONTRIBUTORS
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
from re2o.settings_local import OPTIONNAL_APPS_RE2O
|
from re2o.settings_local import OPTIONNAL_APPS_RE2O
|
||||||
|
|
77
re2o/widgets.py
Normal file
77
re2o/widgets.py
Normal file
|
@ -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
|
|
@ -28,7 +28,8 @@ from django import forms
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.forms import ModelForm, Form
|
from django.forms import ModelForm, Form
|
||||||
from re2o.field_permissions import FieldPermissionFormMixin
|
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 django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from .models import Ticket, CommentTicket
|
from .models import Ticket, CommentTicket
|
||||||
|
@ -59,7 +60,7 @@ class EditTicketForm(FormRevMixin, ModelForm):
|
||||||
model = Ticket
|
model = Ticket
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"user": AutocompleteModelMixin(
|
"user": AutocompleteModelWidget(
|
||||||
url="/users/user-autocomplete",
|
url="/users/user-autocomplete",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,10 +37,10 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from machines.models import Interface
|
from machines.models import Interface
|
||||||
from machines.forms import EditMachineForm, NewMachineForm
|
from machines.forms import EditMachineForm, NewMachineForm
|
||||||
from re2o.mixins import (
|
from re2o.mixins import FormRevMixin
|
||||||
FormRevMixin,
|
from re2o.widgets import (
|
||||||
AutocompleteModelMixin,
|
AutocompleteModelWidget,
|
||||||
AutocompleteMultipleModelMixin,
|
AutocompleteMultipleModelWidget,
|
||||||
)
|
)
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
|
@ -67,13 +67,13 @@ class PortForm(FormRevMixin, ModelForm):
|
||||||
model = Port
|
model = Port
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"switch": AutocompleteModelMixin(url="/topologie/switch-autocomplete"),
|
"switch": AutocompleteModelWidget(url="/topologie/switch-autocomplete"),
|
||||||
"room": AutocompleteModelMixin(url="/topologie/room-autocomplete"),
|
"room": AutocompleteModelWidget(url="/topologie/room-autocomplete"),
|
||||||
"machine_interface": AutocompleteModelMixin(
|
"machine_interface": AutocompleteModelWidget(
|
||||||
url="/machine/machine-autocomplete"
|
url="/machine/machine-autocomplete"
|
||||||
),
|
),
|
||||||
"related": AutocompleteModelMixin(url="/topologie/port-autocomplete"),
|
"related": AutocompleteModelWidget(url="/topologie/port-autocomplete"),
|
||||||
"custom_profile": AutocompleteModelMixin(
|
"custom_profile": AutocompleteModelWidget(
|
||||||
url="/topologie/portprofile-autocomplete"
|
url="/topologie/portprofile-autocomplete"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -181,10 +181,10 @@ class EditSwitchForm(EditMachineForm):
|
||||||
model = Switch
|
model = Switch
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"switchbay": AutocompleteModelMixin(
|
"switchbay": AutocompleteModelWidget(
|
||||||
url="/topologie/switchbay-autocomplete"
|
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
|
model = Room
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"building": AutocompleteModelMixin(url="/topologie/building-autocomplete")
|
"building": AutocompleteModelWidget(url="/topologie/building-autocomplete")
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -222,7 +222,7 @@ class EditModelSwitchForm(FormRevMixin, ModelForm):
|
||||||
|
|
||||||
members = forms.ModelMultipleChoiceField(
|
members = forms.ModelMultipleChoiceField(
|
||||||
Switch.objects.all(),
|
Switch.objects.all(),
|
||||||
widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"),
|
widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"),
|
||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -261,14 +261,14 @@ class EditSwitchBayForm(FormRevMixin, ModelForm):
|
||||||
members = forms.ModelMultipleChoiceField(
|
members = forms.ModelMultipleChoiceField(
|
||||||
Switch.objects.all(),
|
Switch.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"),
|
widget=AutocompleteMultipleModelWidget(url="/topologie/switch-autocomplete"),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SwitchBay
|
model = SwitchBay
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"building": AutocompleteModelMixin(url="/topologie/building-autocomplete")
|
"building": AutocompleteModelWidget(url="/topologie/building-autocomplete")
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -315,10 +315,10 @@ class EditPortProfileForm(FormRevMixin, ModelForm):
|
||||||
model = PortProfile
|
model = PortProfile
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"vlan_tagged": AutocompleteMultipleModelMixin(
|
"vlan_tagged": AutocompleteMultipleModelWidget(
|
||||||
url="/machines/vlan-autocomplete"
|
url="/machines/vlan-autocomplete"
|
||||||
),
|
),
|
||||||
"vlan_untagged": AutocompleteModelMixin(url="/machines/vlan-autocomplete"),
|
"vlan_untagged": AutocompleteModelWidget(url="/machines/vlan-autocomplete"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
|
@ -63,10 +63,10 @@ from topologie.models import Port
|
||||||
from preferences.models import OptionalUser
|
from preferences.models import OptionalUser
|
||||||
from re2o.utils import remove_user_room
|
from re2o.utils import remove_user_room
|
||||||
from re2o.base import get_input_formats_help_text
|
from re2o.base import get_input_formats_help_text
|
||||||
from re2o.mixins import (
|
from re2o.mixins import FormRevMixin
|
||||||
FormRevMixin,
|
from re2o.widgets import (
|
||||||
AutocompleteMultipleModelMixin,
|
AutocompleteMultipleModelWidget,
|
||||||
AutocompleteModelMixin,
|
AutocompleteModelWidget,
|
||||||
)
|
)
|
||||||
from re2o.field_permissions import FieldPermissionFormMixin
|
from re2o.field_permissions import FieldPermissionFormMixin
|
||||||
|
|
||||||
|
@ -351,14 +351,14 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
"room",
|
"room",
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
"school": AutocompleteModelMixin(url="/users/school-autocomplete"),
|
"school": AutocompleteModelWidget(url="/users/school-autocomplete"),
|
||||||
"room": AutocompleteModelMixin(
|
"room": AutocompleteModelWidget(
|
||||||
url="/topologie/room-autocomplete",
|
url="/topologie/room-autocomplete",
|
||||||
attrs={
|
attrs={
|
||||||
"data-minimum-input-length": 3 # Only trigger autocompletion after 3 characters have been typed
|
"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(
|
force = forms.BooleanField(
|
||||||
|
@ -623,9 +623,9 @@ class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
"mailing",
|
"mailing",
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
"school": AutocompleteModelMixin(url="/users/school-autocomplete"),
|
"school": AutocompleteModelWidget(url="/users/school-autocomplete"),
|
||||||
"room": AutocompleteModelMixin(url="/topologie/room-autocomplete"),
|
"room": AutocompleteModelWidget(url="/topologie/room-autocomplete"),
|
||||||
"shell": AutocompleteModelMixin(url="/users/shell-autocomplete"),
|
"shell": AutocompleteModelWidget(url="/users/shell-autocomplete"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def clean_telephone(self):
|
def clean_telephone(self):
|
||||||
|
@ -656,10 +656,10 @@ class ClubAdminandMembersForm(FormRevMixin, ModelForm):
|
||||||
model = Club
|
model = Club
|
||||||
fields = ["administrators", "members"]
|
fields = ["administrators", "members"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"administrators": AutocompleteMultipleModelMixin(
|
"administrators": AutocompleteMultipleModelWidget(
|
||||||
url="/users/adherent-autocomplete"
|
url="/users/adherent-autocomplete"
|
||||||
),
|
),
|
||||||
"members": AutocompleteMultipleModelMixin(
|
"members": AutocompleteMultipleModelWidget(
|
||||||
url="/users/adherent-autocomplete"
|
url="/users/adherent-autocomplete"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue