8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-25 08:23:46 +00:00

Add views, forms and urls for autocomplete topologie

This commit is contained in:
chirac 2020-12-28 13:20:46 +01:00 committed by Gabriel Detraz
parent ec4ddb12e6
commit ec6076d169
3 changed files with 184 additions and 3 deletions

View file

@ -37,7 +37,7 @@ 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 from re2o.mixins import FormRevMixin, AutocompleteModelMixin, AutocompleteMultipleModelMixin
from .models import ( from .models import (
Port, Port,
@ -62,6 +62,23 @@ class PortForm(FormRevMixin, ModelForm):
class Meta: class Meta:
model = Port model = Port
fields = "__all__" fields = "__all__"
widgets = {
"switch": AutocompleteModelMixin(
url="/topologie/switch-autocomplete",
),
"room": AutocompleteModelMixin(
url="/topologie/room-autocomplete",
),
"machine_interface": AutocompleteModelMixin(
url="/machine/machine-autocomplete",
),
"related": AutocompleteModelMixin(
url="/topologie/port-autocomplete",
),
"custom_profile": AutocompleteModelMixin(
url="/topologie/portprofile-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__)
@ -180,6 +197,11 @@ class EditRoomForm(FormRevMixin, ModelForm):
class Meta: class Meta:
model = Room model = Room
fields = "__all__" fields = "__all__"
widgets = {
"building": AutocompleteModelMixin(
url="/topologie/building-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__)
@ -196,7 +218,11 @@ class CreatePortsForm(forms.Form):
class EditModelSwitchForm(FormRevMixin, ModelForm): class EditModelSwitchForm(FormRevMixin, ModelForm):
"""Form used to edit switch models.""" """Form used to edit switch models."""
members = forms.ModelMultipleChoiceField(Switch.objects.all(), required=False) members = forms.ModelMultipleChoiceField(
Switch.objects.all(),
widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"),
required=False
)
class Meta: class Meta:
model = ModelSwitch model = ModelSwitch
@ -230,11 +256,20 @@ class EditConstructorSwitchForm(FormRevMixin, ModelForm):
class EditSwitchBayForm(FormRevMixin, ModelForm): class EditSwitchBayForm(FormRevMixin, ModelForm):
"""Form used to edit switch bays.""" """Form used to edit switch bays."""
members = forms.ModelMultipleChoiceField(Switch.objects.all(), required=False) members = forms.ModelMultipleChoiceField(
Switch.objects.all(),
required=False,
widget=AutocompleteMultipleModelMixin(url="/topologie/switch-autocomplete"),
)
class Meta: class Meta:
model = SwitchBay model = SwitchBay
fields = "__all__" fields = "__all__"
widgets = {
"building": AutocompleteModelMixin(
url="/topologie/building-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__)
@ -279,6 +314,11 @@ class EditPortProfileForm(FormRevMixin, ModelForm):
class Meta: class Meta:
model = PortProfile model = PortProfile
fields = "__all__" fields = "__all__"
widgets = {
"vlan_tagged": AutocompleteMultipleModelMixin(
url="/machine/vlan-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__)

View file

@ -28,6 +28,7 @@ from __future__ import unicode_literals
from django.conf.urls import url from django.conf.urls import url
from . import views from . import views
from . import views_autocomplete
urlpatterns = [ urlpatterns = [
url(r"^$", views.index, name="index"), url(r"^$", views.index, name="index"),
@ -169,4 +170,11 @@ urlpatterns = [
views.del_module_on, views.del_module_on,
name="del-module-on", name="del-module-on",
), ),
### Autocomplete Views
url(r'^room-autocomplete/$', views_autocomplete.RoomAutocomplete.as_view(), name='room-autocomplete',),
url(r'^building-autocomplete/$', views_autocomplete.BuildingAutocomplete.as_view(), name='building-autocomplete',),
url(r'^dormitory-autocomplete/$', views_autocomplete.DormitoryAutocomplete.as_view(), name='dormitory-autocomplete',),
url(r'^switch-autocomplete/$', views_autocomplete.SwitchAutocomplete.as_view(), name='switch-autocomplete',),
url(r'^port-autocomplete/$', views_autocomplete.PortAutocomplete.as_view(), name='profile-autocomplete',),
url(r'^portprofile-autocomplete/$', views_autocomplete.PortProfileAutocomplete.as_view(), name='portprofile-autocomplete',),
] ]

View file

@ -0,0 +1,133 @@
# -*- 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 © 2017-2020 Gabriel Détraz
# Copyright © 2017-2020 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.
# App de gestion des users pour re2o
# Lara Kermarec, Gabriel Détraz, Lemesle Augustin
# Gplv2
"""
Django views autocomplete view
Here are defined the autocomplete class based view.
"""
from __future__ import unicode_literals
from django.db.models import Q, Value, CharField
from django.db.models.functions import Concat
from .models import (
Room,
Dormitory,
Building,
Switch,
PortProfile,
Port,
)
from re2o.mixins import AutocompleteViewMixin
from re2o.acl import (
can_view_all,
)
#@can_view_all(School)
class RoomAutocomplete(AutocompleteViewMixin):
obj_type = Room
# Override get_queryset to add annotations so search behaves more like users expect it to
def get_queryset(self):
# Suppose we have a dorm named Dorm, a building name B, and rooms from 001 - 999
# Comments explain what we try to match
qs = self.obj_type.objects.annotate(
full_name=Concat("building__name", Value(" "), "name"), # Match when the user searches "B 001"
full_name_stuck=Concat("building__name", "name"), # Match "B001"
dorm_name=Concat("building__dormitory__name", Value(" "), "name"), # 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()
if self.q:
qs = qs.filter(
Q(full_name__icontains=self.q)
| Q(full_name_stuck__icontains=self.q)
| Q(dorm_name__icontains=self.q)
| Q(dorm_full_name__icontains=self.q)
| Q(dorm_full_colon_name__icontains=self.q)
)
return qs
#@can_view_all(Dormitory)
class DormitoryAutocomplete(AutocompleteViewMixin):
obj_type = Dormitory
#@can_view_all(Building)
class BuildingAutocomplete(AutocompleteViewMixin):
obj_type = Building
def get_queryset(self):
# We want to be able to filter by dorm so it's easier
qs = self.obj_type.objects.annotate(
full_name=Concat("dormitory__name", Value(" "), "name"),
full_name_colon=Concat("dormitory__name", Value(" : "), "name"),
).all()
if self.q:
qs = qs.filter(
Q(full_name__icontains=self.q)
| Q(full_name_colon__icontains=self.q)
)
return qs
class SwitchAutocomplete(AutocompleteViewMixin):
obj_type = Switch
class PortAutocomplete(AutocompleteViewMixin):
obj_type = Port
def get_queryset(self):
# 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
qs = self.obj_type.objects.annotate(
full_name=Concat("switch__name", Value(" "), "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()),
).all()
if self.q:
qs = qs.filter(
Q(full_name__icontains=self.q)
| Q(full_name_stuck__icontains=self.q)
| Q(full_name_dash__icontains=self.q)
)
return qs
class PortProfileAutocomplete(AutocompleteViewMixin):
obj_type = PortProfile