mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-23 15:33:45 +00:00
Black on files
This commit is contained in:
parent
62561b27de
commit
7ed7a57014
10 changed files with 204 additions and 222 deletions
|
@ -45,7 +45,11 @@ 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 FormRevMixin, AutocompleteModelMixin, AutocompleteMultipleModelMixin
|
from re2o.mixins import (
|
||||||
|
FormRevMixin,
|
||||||
|
AutocompleteModelMixin,
|
||||||
|
AutocompleteMultipleModelMixin,
|
||||||
|
)
|
||||||
from .models import (
|
from .models import (
|
||||||
Article,
|
Article,
|
||||||
Paiement,
|
Paiement,
|
||||||
|
@ -80,12 +84,8 @@ class FactureForm(FieldPermissionFormMixin, FormRevMixin, ModelForm):
|
||||||
model = Facture
|
model = Facture
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"user": AutocompleteModelMixin(
|
"user": AutocompleteModelMixin(url="/users/user-autocomplete"),
|
||||||
url="/users/user-autocomplete",
|
"banque": AutocompleteModelMixin(url="/cotisations/banque-autocomplete"),
|
||||||
),
|
|
||||||
"banque": AutocompleteModelMixin(
|
|
||||||
url="/cotisations/banque-autocomplete",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
|
|
@ -47,10 +47,7 @@ CHOICES_ACTION_TYPE = (
|
||||||
("all", _("All")),
|
("all", _("All")),
|
||||||
)
|
)
|
||||||
|
|
||||||
CHOICES_TYPE = (
|
CHOICES_TYPE = (("ip", _("IPv4")), ("mac", _("MAC address")))
|
||||||
("ip", _("IPv4")),
|
|
||||||
("mac", _("MAC address")),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def all_classes(module):
|
def all_classes(module):
|
||||||
|
@ -88,14 +85,11 @@ def classes_for_action_type(action_type):
|
||||||
users.models.User.__name__,
|
users.models.User.__name__,
|
||||||
users.models.Adherent.__name__,
|
users.models.Adherent.__name__,
|
||||||
users.models.Club.__name__,
|
users.models.Club.__name__,
|
||||||
users.models.EMailAddress.__name__
|
users.models.EMailAddress.__name__,
|
||||||
]
|
]
|
||||||
|
|
||||||
if action_type == "machines":
|
if action_type == "machines":
|
||||||
return [
|
return [machines.models.Machine.__name__, machines.models.Interface.__name__]
|
||||||
machines.models.Machine.__name__,
|
|
||||||
machines.models.Interface.__name__
|
|
||||||
]
|
|
||||||
|
|
||||||
if action_type == "subscriptions":
|
if action_type == "subscriptions":
|
||||||
return all_classes(cotisations.models)
|
return all_classes(cotisations.models)
|
||||||
|
@ -115,6 +109,7 @@ def classes_for_action_type(action_type):
|
||||||
|
|
||||||
class ActionsSearchForm(Form):
|
class ActionsSearchForm(Form):
|
||||||
"""Form used to do an advanced search through the logs."""
|
"""Form used to do an advanced search through the logs."""
|
||||||
|
|
||||||
user = forms.ModelChoiceField(
|
user = forms.ModelChoiceField(
|
||||||
label=_("Performed by"),
|
label=_("Performed by"),
|
||||||
queryset=users.models.User.objects.all(),
|
queryset=users.models.User.objects.all(),
|
||||||
|
@ -143,13 +138,10 @@ class ActionsSearchForm(Form):
|
||||||
|
|
||||||
class MachineHistorySearchForm(Form):
|
class MachineHistorySearchForm(Form):
|
||||||
"""Form used to do a search through the machine histories."""
|
"""Form used to do a search through the machine histories."""
|
||||||
q = forms.CharField(
|
|
||||||
label=_("Search"),
|
q = forms.CharField(label=_("Search"), max_length=100)
|
||||||
max_length=100,
|
|
||||||
)
|
|
||||||
t = forms.CharField(
|
t = forms.CharField(
|
||||||
label=_("Search type"),
|
label=_("Search type"), widget=forms.Select(choices=CHOICES_TYPE)
|
||||||
widget=forms.Select(choices=CHOICES_TYPE)
|
|
||||||
)
|
)
|
||||||
s = forms.DateField(required=False, label=_("Start date"))
|
s = forms.DateField(required=False, label=_("Start date"))
|
||||||
e = forms.DateField(required=False, label=_("End date"))
|
e = forms.DateField(required=False, label=_("End date"))
|
||||||
|
|
|
@ -40,7 +40,11 @@ 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 FormRevMixin, AutocompleteModelMixin, AutocompleteMultipleModelMixin
|
from re2o.mixins import (
|
||||||
|
FormRevMixin,
|
||||||
|
AutocompleteModelMixin,
|
||||||
|
AutocompleteMultipleModelMixin,
|
||||||
|
)
|
||||||
from .models import (
|
from .models import (
|
||||||
Domain,
|
Domain,
|
||||||
Machine,
|
Machine,
|
||||||
|
@ -71,11 +75,7 @@ class EditMachineForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Machine
|
model = Machine
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {"user": AutocompleteModelMixin(url="/users/user-autocomplete")}
|
||||||
"user": AutocompleteModelMixin(
|
|
||||||
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,17 +97,16 @@ 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(
|
"machine": AutocompleteModelMixin(url="/machines/machine-autocomplete"),
|
||||||
url="/machines/machine-autocomplete",
|
|
||||||
),
|
|
||||||
"machine_type": AutocompleteModelMixin(
|
"machine_type": AutocompleteModelMixin(
|
||||||
url="/machines/machinetype-autocomplete",
|
url="/machines/machinetype-autocomplete"
|
||||||
),
|
),
|
||||||
"ipv4": AutocompleteModelMixin(
|
"ipv4": AutocompleteModelMixin(
|
||||||
url="/machines/iplist-autocomplete", forward=['machine_type'],
|
url="/machines/iplist-autocomplete",
|
||||||
|
forward=["machine_type"],
|
||||||
attrs={
|
attrs={
|
||||||
'data-placeholder': 'Automatic assigment. Type to choose specific ip.',
|
"data-placeholder": "Automatic assigment. Type to choose specific ip."
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,9 +158,7 @@ class AliasForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
model = Domain
|
model = Domain
|
||||||
fields = ["name", "extension", "ttl"]
|
fields = ["name", "extension", "ttl"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"extension": AutocompleteModelMixin(
|
"extension": AutocompleteModelMixin(url="/machines/extension-autocomplete")
|
||||||
url="/machines/extension-autocomplete",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -213,9 +210,7 @@ class MachineTypeForm(FormRevMixin, ModelForm):
|
||||||
model = MachineType
|
model = MachineType
|
||||||
fields = ["name", "ip_type"]
|
fields = ["name", "ip_type"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"ip_type": AutocompleteModelMixin(
|
"ip_type": AutocompleteModelMixin(url="/machines/iptype-autocomplete")
|
||||||
url="/machines/iptype-autocomplete",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -252,14 +247,10 @@ class IpTypeForm(FormRevMixin, ModelForm):
|
||||||
model = IpType
|
model = IpType
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"vlan": AutocompleteModelMixin(
|
"vlan": AutocompleteModelMixin(url="/machines/vlan-autocomplete"),
|
||||||
url="/machines/vlan-autocomplete",
|
"extension": AutocompleteModelMixin(url="/machines/extension-autocomplete"),
|
||||||
),
|
|
||||||
"extension": AutocompleteModelMixin(
|
|
||||||
url="/machines/extension-autocomplete",
|
|
||||||
),
|
|
||||||
"ouverture_ports": AutocompleteModelMixin(
|
"ouverture_ports": AutocompleteModelMixin(
|
||||||
url="/machines/ouvertureportlist-autocomplete",
|
url="/machines/ouvertureportlist-autocomplete"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,12 +383,8 @@ class MxForm(FormRevMixin, ModelForm):
|
||||||
model = Mx
|
model = Mx
|
||||||
fields = ["zone", "priority", "name", "ttl"]
|
fields = ["zone", "priority", "name", "ttl"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"zone": AutocompleteModelMixin(
|
"zone": AutocompleteModelMixin(url="/machines/extension-autocomplete"),
|
||||||
url="/machines/extension-autocomplete",
|
"name": AutocompleteModelMixin(url="/machines/domain-autocomplete"),
|
||||||
),
|
|
||||||
"name": AutocompleteModelMixin(
|
|
||||||
url="/machines/domain-autocomplete",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -435,12 +422,8 @@ class NsForm(FormRevMixin, ModelForm):
|
||||||
model = Ns
|
model = Ns
|
||||||
fields = ["zone", "ns", "ttl"]
|
fields = ["zone", "ns", "ttl"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"zone": AutocompleteModelMixin(
|
"zone": AutocompleteModelMixin(url="/machines/extension-autocomplete"),
|
||||||
url="/machines/extension-autocomplete",
|
"ns": AutocompleteModelMixin(url="/machines/domain-autocomplete"),
|
||||||
),
|
|
||||||
"ns": AutocompleteModelMixin(
|
|
||||||
url="/machines/domain-autocomplete",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -476,9 +459,7 @@ class TxtForm(FormRevMixin, ModelForm):
|
||||||
model = Txt
|
model = Txt
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"zone": AutocompleteModelMixin(
|
"zone": AutocompleteModelMixin(url="/machines/extension-autocomplete")
|
||||||
url="/machines/extension-autocomplete",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -511,9 +492,7 @@ class DNameForm(FormRevMixin, ModelForm):
|
||||||
model = DName
|
model = DName
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"zone": AutocompleteModelMixin(
|
"zone": AutocompleteModelMixin(url="/machines/extension-autocomplete")
|
||||||
url="/machines/extension-autocomplete",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -546,12 +525,8 @@ class SrvForm(FormRevMixin, ModelForm):
|
||||||
model = Srv
|
model = Srv
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"extension": AutocompleteModelMixin(
|
"extension": AutocompleteModelMixin(url="/machines/extension-autocomplete"),
|
||||||
url="/machines/extension-autocomplete",
|
"target": AutocompleteModelMixin(url="/machines/domain-autocomplete"),
|
||||||
),
|
|
||||||
"target": AutocompleteModelMixin(
|
|
||||||
url="/machines/domain-autocomplete",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -585,10 +560,10 @@ class NasForm(FormRevMixin, ModelForm):
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"nas_type": AutocompleteModelMixin(
|
"nas_type": AutocompleteModelMixin(
|
||||||
url="/machines/machinetype-autocomplete",
|
url="/machines/machinetype-autocomplete"
|
||||||
),
|
),
|
||||||
"machine_type": AutocompleteModelMixin(
|
"machine_type": AutocompleteModelMixin(
|
||||||
url="/machines/machinetype-autocomplete",
|
url="/machines/machinetype-autocomplete"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,8 +598,8 @@ class RoleForm(FormRevMixin, ModelForm):
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"servers": AutocompleteMultipleModelMixin(
|
"servers": AutocompleteMultipleModelMixin(
|
||||||
url="/machines/interface-autocomplete",
|
url="/machines/interface-autocomplete"
|
||||||
),
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -661,8 +636,8 @@ class ServiceForm(FormRevMixin, ModelForm):
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"servers": AutocompleteMultipleModelMixin(
|
"servers": AutocompleteMultipleModelMixin(
|
||||||
url="/machines/interface-autocomplete",
|
url="/machines/interface-autocomplete"
|
||||||
),
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -750,8 +725,8 @@ class EditOuverturePortConfigForm(FormRevMixin, ModelForm):
|
||||||
fields = ["port_lists"]
|
fields = ["port_lists"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"port_lists": AutocompleteMultipleModelMixin(
|
"port_lists": AutocompleteMultipleModelMixin(
|
||||||
url="/machines/ouvertureportlist-autocomplete",
|
url="/machines/ouvertureportlist-autocomplete"
|
||||||
),
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
|
@ -43,7 +43,7 @@ from .models import (
|
||||||
Extension,
|
Extension,
|
||||||
Domain,
|
Domain,
|
||||||
OuverturePortList,
|
OuverturePortList,
|
||||||
IpList
|
IpList,
|
||||||
)
|
)
|
||||||
|
|
||||||
from re2o.views import AutocompleteViewMixin
|
from re2o.views import AutocompleteViewMixin
|
||||||
|
@ -84,8 +84,7 @@ class InterfaceAutocomplete(AutocompleteViewMixin):
|
||||||
def filter_results(self):
|
def filter_results(self):
|
||||||
if self.q:
|
if self.q:
|
||||||
self.query_set = self.query_set.filter(
|
self.query_set = self.query_set.filter(
|
||||||
Q(domain__name__icontains=self.q)
|
Q(domain__name__icontains=self.q) | Q(machine__name__icontains=self.q)
|
||||||
| Q(machine__name__icontains=self.q)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,11 +93,11 @@ class IpListAutocomplete(AutocompleteViewMixin):
|
||||||
|
|
||||||
# Precision on search to add annotations so search behaves more like users expect it to
|
# Precision on search to add annotations so search behaves more like users expect it to
|
||||||
def filter_results(self):
|
def filter_results(self):
|
||||||
machine_type = self.forwarded.get('machine_type', None)
|
machine_type = self.forwarded.get("machine_type", None)
|
||||||
self.query_set = self.query_set.filter(interface__isnull=True)
|
self.query_set = self.query_set.filter(interface__isnull=True)
|
||||||
if machine_type:
|
if machine_type:
|
||||||
self.query_set = self.query_set.filter(ip_type__machinetype__id=machine_type)
|
|
||||||
if self.q:
|
|
||||||
self.query_set = self.query_set.filter(
|
self.query_set = self.query_set.filter(
|
||||||
Q(ipv4__startswith=self.q)
|
ip_type__machinetype__id=machine_type
|
||||||
)
|
)
|
||||||
|
if self.q:
|
||||||
|
self.query_set = self.query_set.filter(Q(ipv4__startswith=self.q))
|
||||||
|
|
|
@ -29,7 +29,6 @@ from django.utils.translation import ugettext as _
|
||||||
from dal import autocomplete
|
from dal import autocomplete
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RevMixin(object):
|
class RevMixin(object):
|
||||||
"""A mixin to subclass the save and delete function of a model
|
"""A mixin to subclass the save and delete function of a model
|
||||||
to enforce the versioning of the object before those actions
|
to enforce the versioning of the object before those actions
|
||||||
|
@ -260,6 +259,7 @@ class AutocompleteModelMixin(autocomplete.ModelSelect2):
|
||||||
""" A mixin subclassing django-autocomplete-light's Select2 model to pass default options
|
""" 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
|
See https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#passing-options-to-select2
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
select2_attrs = kwargs.get("attrs", {})
|
select2_attrs = kwargs.get("attrs", {})
|
||||||
kwargs["attrs"] = self.fill_default_select2_attrs(select2_attrs)
|
kwargs["attrs"] = self.fill_default_select2_attrs(select2_attrs)
|
||||||
|
@ -271,9 +271,11 @@ class AutocompleteModelMixin(autocomplete.ModelSelect2):
|
||||||
See https://select2.org/configuration/options-api
|
See https://select2.org/configuration/options-api
|
||||||
"""
|
"""
|
||||||
# By default, only trigger autocompletion after 3 characters have been typed
|
# By default, only trigger autocompletion after 3 characters have been typed
|
||||||
#attrs["data-minimum-input-length"] = attrs.get("data-minimum-input-length", 3)
|
# attrs["data-minimum-input-length"] = attrs.get("data-minimum-input-length", 3)
|
||||||
# If there are less than 10 results, just show all of them (no need to autocomplete)
|
# 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)
|
attrs["data-minimum-results-for-search"] = attrs.get(
|
||||||
|
"data-minimum-results-for-search", 10
|
||||||
|
)
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,6 +283,7 @@ class AutocompleteMultipleModelMixin(autocomplete.ModelSelect2Multiple):
|
||||||
""" A mixin subclassing django-autocomplete-light's Select2 model to pass default options
|
""" 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
|
See https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#passing-options-to-select2
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
select2_attrs = kwargs.get("attrs", {})
|
select2_attrs = kwargs.get("attrs", {})
|
||||||
kwargs["attrs"] = self.fill_default_select2_attrs(select2_attrs)
|
kwargs["attrs"] = self.fill_default_select2_attrs(select2_attrs)
|
||||||
|
@ -292,8 +295,9 @@ class AutocompleteMultipleModelMixin(autocomplete.ModelSelect2Multiple):
|
||||||
See https://select2.org/configuration/options-api
|
See https://select2.org/configuration/options-api
|
||||||
"""
|
"""
|
||||||
# By default, only trigger autocompletion after 3 characters have been typed
|
# By default, only trigger autocompletion after 3 characters have been typed
|
||||||
#attrs["data-minimum-input-length"] = attrs.get("data-minimum-input-length", 3)
|
# attrs["data-minimum-input-length"] = attrs.get("data-minimum-input-length", 3)
|
||||||
# If there are less than 10 results, just show all of them (no need to autocomplete)
|
# 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)
|
attrs["data-minimum-results-for-search"] = attrs.get(
|
||||||
|
"data-minimum-results-for-search", 10
|
||||||
|
)
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
|
|
@ -193,5 +193,5 @@ class AutocompleteViewMixin(LoginRequiredMixin, autocomplete.Select2QuerySetView
|
||||||
self.filter_results()
|
self.filter_results()
|
||||||
else:
|
else:
|
||||||
if self.q:
|
if self.q:
|
||||||
self.query_set = self.query_set.filter(**{ self.query_filter: self.q})
|
self.query_set = self.query_set.filter(**{self.query_filter: self.q})
|
||||||
return self.query_set
|
return self.query_set
|
||||||
|
|
|
@ -37,7 +37,11 @@ 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 FormRevMixin, AutocompleteModelMixin, AutocompleteMultipleModelMixin
|
from re2o.mixins import (
|
||||||
|
FormRevMixin,
|
||||||
|
AutocompleteModelMixin,
|
||||||
|
AutocompleteMultipleModelMixin,
|
||||||
|
)
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
Port,
|
Port,
|
||||||
|
@ -63,20 +67,14 @@ class PortForm(FormRevMixin, ModelForm):
|
||||||
model = Port
|
model = Port
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"switch": AutocompleteModelMixin(
|
"switch": AutocompleteModelMixin(url="/topologie/switch-autocomplete"),
|
||||||
url="/topologie/switch-autocomplete",
|
"room": AutocompleteModelMixin(url="/topologie/room-autocomplete"),
|
||||||
),
|
|
||||||
"room": AutocompleteModelMixin(
|
|
||||||
url="/topologie/room-autocomplete",
|
|
||||||
),
|
|
||||||
"machine_interface": AutocompleteModelMixin(
|
"machine_interface": AutocompleteModelMixin(
|
||||||
url="/machine/machine-autocomplete",
|
url="/machine/machine-autocomplete"
|
||||||
),
|
|
||||||
"related": AutocompleteModelMixin(
|
|
||||||
url="/topologie/port-autocomplete",
|
|
||||||
),
|
),
|
||||||
|
"related": AutocompleteModelMixin(url="/topologie/port-autocomplete"),
|
||||||
"custom_profile": AutocompleteModelMixin(
|
"custom_profile": AutocompleteModelMixin(
|
||||||
url="/topologie/portprofile-autocomplete",
|
url="/topologie/portprofile-autocomplete"
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,11 +182,9 @@ class EditSwitchForm(EditMachineForm):
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"switchbay": AutocompleteModelMixin(
|
"switchbay": AutocompleteModelMixin(
|
||||||
url="/topologie/switchbay-autocomplete",
|
url="/topologie/switchbay-autocomplete"
|
||||||
),
|
|
||||||
"user": AutocompleteModelMixin(
|
|
||||||
url="/users/user-autocomplete",
|
|
||||||
),
|
),
|
||||||
|
"user": AutocompleteModelMixin(url="/users/user-autocomplete"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,9 +202,7 @@ class EditRoomForm(FormRevMixin, ModelForm):
|
||||||
model = Room
|
model = Room
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"building": AutocompleteModelMixin(
|
"building": AutocompleteModelMixin(url="/topologie/building-autocomplete")
|
||||||
url="/topologie/building-autocomplete",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -229,7 +223,7 @@ class EditModelSwitchForm(FormRevMixin, ModelForm):
|
||||||
members = forms.ModelMultipleChoiceField(
|
members = forms.ModelMultipleChoiceField(
|
||||||
Switch.objects.all(),
|
Switch.objects.all(),
|
||||||
widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"),
|
widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"),
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -274,9 +268,7 @@ class EditSwitchBayForm(FormRevMixin, ModelForm):
|
||||||
model = SwitchBay
|
model = SwitchBay
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"building": AutocompleteModelMixin(
|
"building": AutocompleteModelMixin(url="/topologie/building-autocomplete")
|
||||||
url="/topologie/building-autocomplete",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -324,11 +316,9 @@ class EditPortProfileForm(FormRevMixin, ModelForm):
|
||||||
fields = "__all__"
|
fields = "__all__"
|
||||||
widgets = {
|
widgets = {
|
||||||
"vlan_tagged": AutocompleteMultipleModelMixin(
|
"vlan_tagged": AutocompleteMultipleModelMixin(
|
||||||
url="/machines/vlan-autocomplete",
|
url="/machines/vlan-autocomplete"
|
||||||
),
|
|
||||||
"vlan_untagged": AutocompleteModelMixin(
|
|
||||||
url="/machines/vlan-autocomplete",
|
|
||||||
),
|
),
|
||||||
|
"vlan_untagged": AutocompleteModelMixin(url="/machines/vlan-autocomplete"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
|
@ -34,15 +34,7 @@ from __future__ import unicode_literals
|
||||||
from django.db.models import Q, Value, CharField
|
from django.db.models import Q, Value, CharField
|
||||||
from django.db.models.functions import Concat
|
from django.db.models.functions import Concat
|
||||||
|
|
||||||
from .models import (
|
from .models import Room, Dormitory, Building, Switch, PortProfile, Port, SwitchBay
|
||||||
Room,
|
|
||||||
Dormitory,
|
|
||||||
Building,
|
|
||||||
Switch,
|
|
||||||
PortProfile,
|
|
||||||
Port,
|
|
||||||
SwitchBay,
|
|
||||||
)
|
|
||||||
|
|
||||||
from re2o.views import AutocompleteViewMixin
|
from re2o.views import AutocompleteViewMixin
|
||||||
|
|
||||||
|
@ -55,11 +47,27 @@ class RoomAutocomplete(AutocompleteViewMixin):
|
||||||
# Suppose we have a dorm named Dorm, a building name B, and rooms from 001 - 999
|
# Suppose we have a dorm named Dorm, a building name B, and rooms from 001 - 999
|
||||||
# Comments explain what we try to match
|
# Comments explain what we try to match
|
||||||
self.query_set = self.query_set.annotate(
|
self.query_set = self.query_set.annotate(
|
||||||
full_name=Concat("building__name", Value(" "), "name"), # Match when the user searches "B 001"
|
full_name=Concat(
|
||||||
|
"building__name", Value(" "), "name"
|
||||||
|
), # Match when the user searches "B 001"
|
||||||
full_name_stuck=Concat("building__name", "name"), # Match "B001"
|
full_name_stuck=Concat("building__name", "name"), # Match "B001"
|
||||||
dorm_name=Concat("building__dormitory__name", Value(" "), "name"), # Match "Dorm 001"
|
dorm_name=Concat(
|
||||||
dorm_full_name=Concat("building__dormitory__name", Value(" "), "building__name", Value(" "), "name"), # Match "Dorm B 001"
|
"building__dormitory__name", Value(" "), "name"
|
||||||
dorm_full_colon_name=Concat("building__dormitory__name", Value(" : "), "building__name", Value(" "), "name"), # Match "Dorm : B 001" (see Room's full_name property)
|
), # Match "Dorm 001"
|
||||||
|
dorm_full_name=Concat(
|
||||||
|
"building__dormitory__name",
|
||||||
|
Value(" "),
|
||||||
|
"building__name",
|
||||||
|
Value(" "),
|
||||||
|
"name",
|
||||||
|
), # Match "Dorm B 001"
|
||||||
|
dorm_full_colon_name=Concat(
|
||||||
|
"building__dormitory__name",
|
||||||
|
Value(" : "),
|
||||||
|
"building__name",
|
||||||
|
Value(" "),
|
||||||
|
"name",
|
||||||
|
), # Match "Dorm : B 001" (see Room's full_name property)
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
if self.q:
|
if self.q:
|
||||||
|
@ -89,8 +97,7 @@ class BuildingAutocomplete(AutocompleteViewMixin):
|
||||||
|
|
||||||
if self.q:
|
if self.q:
|
||||||
self.query_set = self.query_set.filter(
|
self.query_set = self.query_set.filter(
|
||||||
Q(full_name__icontains=self.q)
|
Q(full_name__icontains=self.q) | Q(full_name_colon__icontains=self.q)
|
||||||
| Q(full_name_colon__icontains=self.q)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,9 +113,13 @@ class PortAutocomplete(AutocompleteViewMixin):
|
||||||
# We want to enter the switch name, not just the port number
|
# We want to enter the switch name, not just the port number
|
||||||
# Because we're concatenating a CharField and an Integer, we have to sepcify the output_field
|
# Because we're concatenating a CharField and an Integer, we have to sepcify the output_field
|
||||||
self.query_set = self.query_set.annotate(
|
self.query_set = self.query_set.annotate(
|
||||||
full_name=Concat("switch__name", Value(" "), "port", output_field=CharField()),
|
full_name=Concat(
|
||||||
|
"switch__name", Value(" "), "port", output_field=CharField()
|
||||||
|
),
|
||||||
full_name_stuck=Concat("switch__name", "port", output_field=CharField()),
|
full_name_stuck=Concat("switch__name", "port", output_field=CharField()),
|
||||||
full_name_dash=Concat("switch__name", Value(" - "), "port", output_field=CharField()),
|
full_name_dash=Concat(
|
||||||
|
"switch__name", Value(" - "), "port", output_field=CharField()
|
||||||
|
),
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
if self.q:
|
if self.q:
|
||||||
|
@ -126,9 +137,19 @@ class SwitchBayAutocomplete(AutocompleteViewMixin):
|
||||||
def filter_results(self):
|
def filter_results(self):
|
||||||
# Comments explain what we try to match
|
# Comments explain what we try to match
|
||||||
self.query_set = self.query_set.annotate(
|
self.query_set = self.query_set.annotate(
|
||||||
full_name=Concat("building__name", Value(" "), "name"), # Match when the user searches ""
|
full_name=Concat(
|
||||||
dorm_name=Concat("building__dormitory__name", Value(" "), "name"), # Match "Dorm Local Sud"
|
"building__name", Value(" "), "name"
|
||||||
dorm_full_name=Concat("building__dormitory__name", Value(" "), "building__name", Value(" "), "name"), # Match "Dorm J Local Sud"
|
), # Match when the user searches ""
|
||||||
|
dorm_name=Concat(
|
||||||
|
"building__dormitory__name", Value(" "), "name"
|
||||||
|
), # Match "Dorm Local Sud"
|
||||||
|
dorm_full_name=Concat(
|
||||||
|
"building__dormitory__name",
|
||||||
|
Value(" "),
|
||||||
|
"building__name",
|
||||||
|
Value(" "),
|
||||||
|
"name",
|
||||||
|
), # Match "Dorm J Local Sud"
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
if self.q:
|
if self.q:
|
||||||
|
|
|
@ -46,7 +46,10 @@ from os import walk, path
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.forms import ModelForm, Form
|
from django.forms import ModelForm, Form
|
||||||
from django.contrib.auth.forms import ReadOnlyPasswordHashField
|
from django.contrib.auth.forms import ReadOnlyPasswordHashField
|
||||||
from django.contrib.auth.password_validation import validate_password, password_validators_help_text_html
|
from django.contrib.auth.password_validation import (
|
||||||
|
validate_password,
|
||||||
|
password_validators_help_text_html,
|
||||||
|
)
|
||||||
from django.core.validators import MinLengthValidator
|
from django.core.validators import MinLengthValidator
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
@ -60,7 +63,11 @@ 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 FormRevMixin, AutocompleteMultipleModelMixin, AutocompleteModelMixin
|
from re2o.mixins import (
|
||||||
|
FormRevMixin,
|
||||||
|
AutocompleteMultipleModelMixin,
|
||||||
|
AutocompleteModelMixin,
|
||||||
|
)
|
||||||
from re2o.field_permissions import FieldPermissionFormMixin
|
from re2o.field_permissions import FieldPermissionFormMixin
|
||||||
|
|
||||||
from preferences.models import GeneralOption
|
from preferences.models import GeneralOption
|
||||||
|
@ -156,14 +163,10 @@ class ServiceUserAdminForm(FormRevMixin, forms.ModelForm):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
password1 = forms.CharField(
|
password1 = forms.CharField(
|
||||||
label=_("Password"),
|
label=_("Password"), widget=forms.PasswordInput, max_length=255
|
||||||
widget=forms.PasswordInput,
|
|
||||||
max_length=255,
|
|
||||||
)
|
)
|
||||||
password2 = forms.CharField(
|
password2 = forms.CharField(
|
||||||
label=_("Password confirmation"),
|
label=_("Password confirmation"), widget=forms.PasswordInput, max_length=255
|
||||||
widget=forms.PasswordInput,
|
|
||||||
max_length=255,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -215,6 +218,7 @@ class PassForm(FormRevMixin, FieldPermissionFormMixin, forms.ModelForm):
|
||||||
DjangoForm : Inherit from basic django form
|
DjangoForm : Inherit from basic django form
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
selfpasswd = forms.CharField(
|
selfpasswd = forms.CharField(
|
||||||
label=_("Current password"), max_length=255, widget=forms.PasswordInput
|
label=_("Current password"), max_length=255, widget=forms.PasswordInput
|
||||||
)
|
)
|
||||||
|
@ -222,12 +226,10 @@ class PassForm(FormRevMixin, FieldPermissionFormMixin, forms.ModelForm):
|
||||||
label=_("New password"),
|
label=_("New password"),
|
||||||
max_length=255,
|
max_length=255,
|
||||||
widget=forms.PasswordInput,
|
widget=forms.PasswordInput,
|
||||||
help_text=password_validators_help_text_html()
|
help_text=password_validators_help_text_html(),
|
||||||
)
|
)
|
||||||
passwd2 = forms.CharField(
|
passwd2 = forms.CharField(
|
||||||
label=_("New password confirmation"),
|
label=_("New password confirmation"), max_length=255, widget=forms.PasswordInput
|
||||||
max_length=255,
|
|
||||||
widget=forms.PasswordInput,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -296,9 +298,7 @@ class MassArchiveForm(forms.Form):
|
||||||
|
|
||||||
date = forms.DateTimeField(help_text="%d/%m/%y")
|
date = forms.DateTimeField(help_text="%d/%m/%y")
|
||||||
full_archive = forms.BooleanField(
|
full_archive = forms.BooleanField(
|
||||||
label=_(
|
label=_("Fully archive users? WARNING: CRITICAL OPERATION IF TRUE"),
|
||||||
"Fully archive users? WARNING: CRITICAL OPERATION IF TRUE"
|
|
||||||
),
|
|
||||||
initial=False,
|
initial=False,
|
||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
|
@ -351,18 +351,14 @@ class AdherentForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
"room",
|
"room",
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
"school": AutocompleteModelMixin(
|
"school": AutocompleteModelMixin(url="/users/school-autocomplete"),
|
||||||
url="/users/school-autocomplete",
|
|
||||||
),
|
|
||||||
"room": AutocompleteModelMixin(
|
"room": AutocompleteModelMixin(
|
||||||
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(
|
"shell": AutocompleteModelMixin(url="/users/shell-autocomplete"),
|
||||||
url="/users/shell-autocomplete",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
force = forms.BooleanField(
|
force = forms.BooleanField(
|
||||||
|
@ -427,6 +423,7 @@ class AdherentCreationForm(AdherentForm):
|
||||||
Parameters:
|
Parameters:
|
||||||
DjangoForm : Inherit from basic django form
|
DjangoForm : Inherit from basic django form
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Champ pour choisir si un lien est envoyé par mail pour le mot de passe
|
# Champ pour choisir si un lien est envoyé par mail pour le mot de passe
|
||||||
init_password_by_mail_info = _(
|
init_password_by_mail_info = _(
|
||||||
"If this options is set, you will receive a link to set"
|
"If this options is set, you will receive a link to set"
|
||||||
|
@ -439,9 +436,7 @@ class AdherentCreationForm(AdherentForm):
|
||||||
)
|
)
|
||||||
|
|
||||||
init_password_by_mail = forms.BooleanField(
|
init_password_by_mail = forms.BooleanField(
|
||||||
help_text=init_password_by_mail_info,
|
help_text=init_password_by_mail_info, required=False, initial=True
|
||||||
required=False,
|
|
||||||
initial=True
|
|
||||||
)
|
)
|
||||||
init_password_by_mail.label = _("Send password reset link by email.")
|
init_password_by_mail.label = _("Send password reset link by email.")
|
||||||
|
|
||||||
|
@ -452,7 +447,7 @@ class AdherentCreationForm(AdherentForm):
|
||||||
label=_("Password"),
|
label=_("Password"),
|
||||||
widget=forms.PasswordInput,
|
widget=forms.PasswordInput,
|
||||||
max_length=255,
|
max_length=255,
|
||||||
help_text=password_validators_help_text_html()
|
help_text=password_validators_help_text_html(),
|
||||||
)
|
)
|
||||||
password2 = forms.CharField(
|
password2 = forms.CharField(
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -542,8 +537,12 @@ class AdherentCreationForm(AdherentForm):
|
||||||
# Save the provided password in hashed format
|
# Save the provided password in hashed format
|
||||||
user = super(AdherentForm, self).save(commit=False)
|
user = super(AdherentForm, self).save(commit=False)
|
||||||
|
|
||||||
is_set_password_allowed = OptionalUser.get_cached_value("allow_set_password_during_user_creation")
|
is_set_password_allowed = OptionalUser.get_cached_value(
|
||||||
set_passwd = is_set_password_allowed and not self.cleaned_data.get("init_password_by_mail")
|
"allow_set_password_during_user_creation"
|
||||||
|
)
|
||||||
|
set_passwd = is_set_password_allowed and not self.cleaned_data.get(
|
||||||
|
"init_password_by_mail"
|
||||||
|
)
|
||||||
if set_passwd:
|
if set_passwd:
|
||||||
user.set_password(self.cleaned_data["password1"])
|
user.set_password(self.cleaned_data["password1"])
|
||||||
|
|
||||||
|
@ -624,15 +623,9 @@ class ClubForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
|
||||||
"mailing",
|
"mailing",
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
"school": AutocompleteModelMixin(
|
"school": AutocompleteModelMixin(url="/users/school-autocomplete"),
|
||||||
url="/users/school-autocomplete",
|
"room": AutocompleteModelMixin(url="/topologie/room-autocomplete"),
|
||||||
),
|
"shell": AutocompleteModelMixin(url="/users/shell-autocomplete"),
|
||||||
"room": AutocompleteModelMixin(
|
|
||||||
url="/topologie/room-autocomplete",
|
|
||||||
),
|
|
||||||
"shell": AutocompleteModelMixin(
|
|
||||||
url="/users/shell-autocomplete",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def clean_telephone(self):
|
def clean_telephone(self):
|
||||||
|
@ -664,11 +657,11 @@ class ClubAdminandMembersForm(FormRevMixin, ModelForm):
|
||||||
fields = ["administrators", "members"]
|
fields = ["administrators", "members"]
|
||||||
widgets = {
|
widgets = {
|
||||||
"administrators": AutocompleteMultipleModelMixin(
|
"administrators": AutocompleteMultipleModelMixin(
|
||||||
url="/users/adherent-autocomplete",
|
url="/users/adherent-autocomplete"
|
||||||
),
|
),
|
||||||
"members": AutocompleteMultipleModelMixin(
|
"members": AutocompleteMultipleModelMixin(
|
||||||
url="/users/adherent-autocomplete",
|
url="/users/adherent-autocomplete"
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
@ -1005,6 +998,7 @@ class InitialRegisterForm(forms.Form):
|
||||||
Parameters:
|
Parameters:
|
||||||
DjangoForm : Inherit from basic django form
|
DjangoForm : Inherit from basic django form
|
||||||
"""
|
"""
|
||||||
|
|
||||||
register_room = forms.BooleanField(required=False)
|
register_room = forms.BooleanField(required=False)
|
||||||
register_machine = forms.BooleanField(required=False)
|
register_machine = forms.BooleanField(required=False)
|
||||||
|
|
||||||
|
@ -1085,8 +1079,8 @@ class ThemeForm(FormRevMixin, forms.Form):
|
||||||
theme = forms.ChoiceField(widget=forms.Select())
|
theme = forms.ChoiceField(widget=forms.Select())
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
_, _ ,themes = next(walk(path.join(settings.STATIC_ROOT, "css/themes")))
|
_, _, themes = next(walk(path.join(settings.STATIC_ROOT, "css/themes")))
|
||||||
if not themes:
|
if not themes:
|
||||||
themes = ["default.css"]
|
themes = ["default.css"]
|
||||||
super(ThemeForm, self).__init__(*args, **kwargs)
|
super(ThemeForm, self).__init__(*args, **kwargs)
|
||||||
self.fields['theme'].choices = [(theme, theme) for theme in themes]
|
self.fields["theme"].choices = [(theme, theme) for theme in themes]
|
||||||
|
|
|
@ -31,22 +31,18 @@ Here are defined the autocomplete class based view.
|
||||||
"""
|
"""
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .models import (
|
from .models import User, School, Adherent, Club, ListShell
|
||||||
User,
|
|
||||||
School,
|
|
||||||
Adherent,
|
|
||||||
Club,
|
|
||||||
ListShell,
|
|
||||||
)
|
|
||||||
|
|
||||||
from re2o.views import AutocompleteViewMixin
|
from re2o.views import AutocompleteViewMixin
|
||||||
|
|
||||||
from django.db.models import Q, Value, CharField
|
from django.db.models import Q, Value, CharField
|
||||||
from django.db.models.functions import Concat
|
from django.db.models.functions import Concat
|
||||||
|
|
||||||
|
|
||||||
class SchoolAutocomplete(AutocompleteViewMixin):
|
class SchoolAutocomplete(AutocompleteViewMixin):
|
||||||
obj_type = School
|
obj_type = School
|
||||||
|
|
||||||
|
|
||||||
class UserAutocomplete(AutocompleteViewMixin):
|
class UserAutocomplete(AutocompleteViewMixin):
|
||||||
obj_type = User
|
obj_type = User
|
||||||
|
|
||||||
|
@ -54,8 +50,12 @@ class UserAutocomplete(AutocompleteViewMixin):
|
||||||
def filter_results(self):
|
def filter_results(self):
|
||||||
# Comments explain what we try to match
|
# Comments explain what we try to match
|
||||||
self.query_set = self.query_set.annotate(
|
self.query_set = self.query_set.annotate(
|
||||||
full_name=Concat("adherent__name", Value(" "), "surname"), # Match when the user searches "Toto Passoir"
|
full_name=Concat(
|
||||||
full_name_reverse=Concat("surname", Value(" "), "adherent__name"), # Match when the user searches "Passoir Toto"
|
"adherent__name", Value(" "), "surname"
|
||||||
|
), # Match when the user searches "Toto Passoir"
|
||||||
|
full_name_reverse=Concat(
|
||||||
|
"surname", Value(" "), "adherent__name"
|
||||||
|
), # Match when the user searches "Passoir Toto"
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
if self.q:
|
if self.q:
|
||||||
|
@ -65,6 +65,7 @@ class UserAutocomplete(AutocompleteViewMixin):
|
||||||
| Q(full_name_reverse__icontains=self.q)
|
| Q(full_name_reverse__icontains=self.q)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class AdherentAutocomplete(AutocompleteViewMixin):
|
class AdherentAutocomplete(AutocompleteViewMixin):
|
||||||
obj_type = Adherent
|
obj_type = Adherent
|
||||||
|
|
||||||
|
@ -72,8 +73,12 @@ class AdherentAutocomplete(AutocompleteViewMixin):
|
||||||
def filter_results(self):
|
def filter_results(self):
|
||||||
# Comments explain what we try to match
|
# Comments explain what we try to match
|
||||||
self.query_set = self.query_set.annotate(
|
self.query_set = self.query_set.annotate(
|
||||||
full_name=Concat("name", Value(" "), "surname"), # Match when the user searches "Toto Passoir"
|
full_name=Concat(
|
||||||
full_name_reverse=Concat("surname", Value(" "), "name"), # Match when the user searches "Passoir Toto"
|
"name", Value(" "), "surname"
|
||||||
|
), # Match when the user searches "Toto Passoir"
|
||||||
|
full_name_reverse=Concat(
|
||||||
|
"surname", Value(" "), "name"
|
||||||
|
), # Match when the user searches "Passoir Toto"
|
||||||
).all()
|
).all()
|
||||||
|
|
||||||
if self.q:
|
if self.q:
|
||||||
|
@ -83,9 +88,11 @@ class AdherentAutocomplete(AutocompleteViewMixin):
|
||||||
| Q(full_name_reverse__icontains=self.q)
|
| Q(full_name_reverse__icontains=self.q)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ClubAutocomplete(AutocompleteViewMixin):
|
class ClubAutocomplete(AutocompleteViewMixin):
|
||||||
obj_type = Club
|
obj_type = Club
|
||||||
|
|
||||||
|
|
||||||
class ShellAutocomplete(AutocompleteViewMixin):
|
class ShellAutocomplete(AutocompleteViewMixin):
|
||||||
obj_type = ListShell
|
obj_type = ListShell
|
||||||
query_filter = "shell__icontains"
|
query_filter = "shell__icontains"
|
||||||
|
|
Loading…
Reference in a new issue