From bba28ee4d9d6cac42b8eaf5019080dffd957e303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Kervella?= Date: Sat, 7 Oct 2017 17:00:55 +0000 Subject: [PATCH] =?UTF-8?q?Utilise=20les=20nouveaus=20param=20bft=20et=20c?= =?UTF-8?q?hange=20la=20structure=20de=20donn=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les nouveaux paramètres passés permettent de reload entièrement la source de données du typeahead quand le champ field est changé, ce qui permet au moteur de recherche de ne traiter que les données voulues et non de devoir filtrer ce qu'il faut afficher ou non parmis l'ensemble des ip possibles (tout type confondus). --- machines/forms.py | 15 ++++--- machines/views.py | 110 ++++++++++++++++++++++++++++++---------------- 2 files changed, 81 insertions(+), 44 deletions(-) diff --git a/machines/forms.py b/machines/forms.py index ca94414e..c9a3873f 100644 --- a/machines/forms.py +++ b/machines/forms.py @@ -63,9 +63,9 @@ class EditInterfaceForm(ModelForm): self.fields['type'].empty_label = "Séléctionner un type de machine" if "ipv4" in self.fields: self.fields['ipv4'].empty_label = "Assignation automatique de l'ipv4" - self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).annotate(type=F('ip_type__machinetype__id')) + self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).annotate(mtype_id=F('ip_type__machinetype__id')) # Add it's own address - self.fields['ipv4'].queryset |= IpList.objects.filter(id=self.fields['ipv4'].get_bound_field(self, 'ipv4').value()).annotate(type=F('ip_type__machinetype__id')) + self.fields['ipv4'].queryset |= IpList.objects.filter(id=self.fields['ipv4'].get_bound_field(self, 'ipv4').value()).annotate(mtype_id=F('ip_type__machinetype__id')) if "machine" in self.fields: self.fields['machine'].queryset = Machine.objects.all().select_related('user') @@ -79,9 +79,9 @@ class AddInterfaceForm(EditInterfaceForm): self.fields['ipv4'].empty_label = "Assignation automatique de l'ipv4" if not infra: self.fields['type'].queryset = MachineType.objects.filter(ip_type__in=IpType.objects.filter(need_infra=False)) - self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).filter(ip_type__in=IpType.objects.filter(need_infra=False)).annotate(type=F('ip_type__machinetype__id')) + self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).filter(ip_type__in=IpType.objects.filter(need_infra=False)).annotate(mtype_id=F('ip_type__machinetype__id')) else: - self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).annotate(type=F('ip_type__machinetype__id')) + self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).annotate(mtype_id=F('ip_type__machinetype__id')) class NewInterfaceForm(EditInterfaceForm): class Meta(EditInterfaceForm.Meta): @@ -97,11 +97,12 @@ class BaseEditInterfaceForm(EditInterfaceForm): self.fields['ipv4'].empty_label = "Assignation automatique de l'ipv4" if not infra: self.fields['type'].queryset = MachineType.objects.filter(ip_type__in=IpType.objects.filter(need_infra=False)) - self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).filter(ip_type__in=IpType.objects.filter(need_infra=False)).annotate(type=F('ip_type__machinetype__id')) + self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).filter(ip_type__in=IpType.objects.filter(need_infra=False)).annotate(mtype_id=F('ip_type__machinetype__id')) # Add it's own address - self.fields['ipv4'].queryset |= IpList.objects.filter(id=self.fields['ipv4'].get_bound_field(self, 'ipv4').value()).annotate(type=F('ip_type__machinetype__id')) + self.fields['ipv4'].queryset |= IpList.objects.filter(id=self.fields['ipv4'].get_bound_field(self, 'ipv4').value()).annotate(mtype_id=F('ip_type__machinetype__id')) else: - self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).annotate(type=F('ip_type__machinetype__id')) + self.fields['ipv4'].queryset = IpList.objects.filter(interface__isnull=True).annotate(mtype_id=F('ip_type__machinetype__id')) + self.fields['ipv4'].queryset |= IpList.objects.filter(id=self.fields['ipv4'].get_bound_field(self, 'ipv4').value()).annotate(mtype_id=F('ip_type__machinetype__id')) class AliasForm(ModelForm): class Meta: diff --git a/machines/views.py b/machines/views.py index ddc5b18f..d9c59b15 100644 --- a/machines/views.py +++ b/machines/views.py @@ -55,6 +55,7 @@ from .models import IpType, Machine, Interface, IpList, MachineType, Extension, from users.models import User from users.models import all_has_access from preferences.models import GeneralOption, OptionalMachine +from .templatetags.bootstrap_form_typeahead import hidden_id, input_id def all_active_interfaces(): """Renvoie l'ensemble des machines autorisées à sortir sur internet """ @@ -77,42 +78,80 @@ def form(ctx, template, request): c.update(csrf(request)) return render(request, template, c) -def generate_ipv4_choices( field ) : - return '[{key: "", value: "' + str(field.empty_label) + '", type: -1},' + \ - ', '.join([ \ - '{key: ' + str(ip.id) + ',' \ - ' value: "' + str(ip.ipv4) + '",' \ - ' type: ' + str(ip.type) + '}' \ - for ip in field.queryset \ - ]) + \ - '];' +def f_type_id( is_type_tt ): + """ The id that will be used in HTML to store the value of the field + type. Depends on the fact that type is generate using typeahead or not + """ + return hidden_id('type') if is_type_tt else input_id('type') -def generate_ipv4_match_func() : +def generate_ipv4_choices( form ) : + """ Generate the parameter choices for the bootstrap_form_typeahead tag + """ + f_ipv4 = form.fields['ipv4'] + used_mtype_id = [] + choices = '{ "": [{key: "", value: "Choisissez d\'abord un type de machine"},' + mtype_id = -1 + + for ip in f_ipv4.queryset.order_by('mtype_id', 'id') : + if mtype_id != ip.mtype_id : + mtype_id = ip.mtype_id + used_mtype_id.append(mtype_id) + choices += '], "'+str(mtype_id)+'": [' + choices += '{key: "", value: "' + str(f_ipv4.empty_label) + '"},' + choices += '{key: ' + str(ip.id) + ', value: "' + str(ip.ipv4) + '"},' + + for t in form.fields['type'].queryset.exclude(id__in=used_mtype_id) : + choices += '], "'+str(t.id)+'": [' + choices += '{key: "", value: "' + str(f_ipv4.empty_label) + '"},' + choices += ']}' + return choices + +def generate_ipv4_engine( is_type_tt ) : + """ Generate the parameter engine for the bootstrap_form_typeahead tag + """ + return 'new Bloodhound({ ' \ + 'datumTokenizer: Bloodhound.tokenizers.obj.whitespace("value"), ' \ + 'queryTokenizer: Bloodhound.tokenizers.whitespace, ' \ + 'local: choices_ipv4[$("#'+f_type_id(is_type_tt)+'").val()], ' \ + 'identify: function(obj) { return obj.key; } ' \ + '})' + +def generate_ipv4_match_func( is_type_tt ) : + """ Generate the parameter match_func for the bootstrap_form_typeahead tag + """ return 'function(q, sync) {' \ - 'var select = function (array, nb, filter) {' \ - 'var i=0; var res=[];' \ - 'while (nb >= 0 && i < array.length) {' \ - 'if (filter(array[i])) {' \ - 'res.push(array[i]);' \ - 'nb -= 1;' \ - '}' \ - 'i += 1;' \ - '}' \ - 'return res;' \ - '};' \ - 'var filter = function (elt) {' \ - 'return elt.type == -1 || elt.type == $("#id_type").val();' \ - '};' \ - 'var cb = function (a) { sync(a.filter(filter)); };' \ 'if (q === "") {' \ - 'sync( engine.get( select(choices_ipv4, 10, filter).map(' \ - 'function (elt) { return elt.key; }' \ - ') ) );' \ + 'var nb = 10;' \ + 'var first = [] ;' \ + 'for(' \ + 'var i=0 ;' \ + 'i