mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-26 22:52:26 +00:00
Merge branch 'search' into 'master'
Search See merge request rezo/re2o!28
This commit is contained in:
commit
8fbb1c5b04
11 changed files with 448 additions and 194 deletions
|
@ -36,7 +36,9 @@ def url_insert_param(url="", **kwargs):
|
|||
Return the URL with some specific parameters inserted into the query
|
||||
part. If a URL has already some parameters, those requested will be
|
||||
modified if already exisiting or will be added and the other parameters
|
||||
will stay unmodified.
|
||||
will stay unmodified. If parameters with the same name are already in the
|
||||
URL and a value is specified for this parameter, it will replace all
|
||||
existing parameters.
|
||||
|
||||
**Tag name**::
|
||||
|
||||
|
@ -82,18 +84,21 @@ def url_insert_param(url="", **kwargs):
|
|||
# Get existing parameters in the url
|
||||
params = {}
|
||||
if '?' in url:
|
||||
url, params = url.split('?', maxsplit=1)
|
||||
params = {
|
||||
p[:p.find('=')]: p[p.find('=')+1:] for p in params.split('&')
|
||||
}
|
||||
url, parameters = url.split('?', maxsplit=1)
|
||||
for parameter in parameters.split('&'):
|
||||
p_name, p_value = parameter.split('=', maxsplit=1)
|
||||
if p_name not in params:
|
||||
params[p_name] = []
|
||||
params[p_name].append(p_value)
|
||||
|
||||
# Add the request parameters to the list of parameters
|
||||
for key, value in kwargs.items():
|
||||
params[key] = value
|
||||
params[key] = [value]
|
||||
|
||||
# Write the url
|
||||
url += '?'
|
||||
for param, value in params.items():
|
||||
for param, value_list in params.items():
|
||||
for value in value_list:
|
||||
url += str(param) + '=' + str(value) + '&'
|
||||
|
||||
# Remove the last '&' (or '?' if no parameters)
|
||||
|
|
|
@ -248,7 +248,7 @@ class SortTable:
|
|||
if not fields:
|
||||
fields = values.get('default', [])
|
||||
request = request.order_by(*fields)
|
||||
if order == 'desc':
|
||||
if values.get(col, None) and order == 'desc':
|
||||
return request.reverse()
|
||||
else:
|
||||
return request
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
"""The field used in the admin view for the search app"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
|
|
|
@ -20,21 +20,72 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
"""The forms used by the search app"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db.models import Q
|
||||
from simple_search import BaseSearchForm
|
||||
from django import forms
|
||||
from django.forms import Form
|
||||
|
||||
from users.models import User, School
|
||||
|
||||
class UserSearchForm(BaseSearchForm):
|
||||
class Meta:
|
||||
base_qs = User.objects
|
||||
search_fields = ('^name', 'description', 'specifications', '=id')
|
||||
|
||||
# assumes a fulltext index has been defined on the fields
|
||||
# 'name,description,specifications,id'
|
||||
fulltext_indexes = (
|
||||
('name', 2), # name matches are weighted higher
|
||||
('name,description,specifications,id', 1),
|
||||
CHOICES_USER = (
|
||||
('0', 'Actifs'),
|
||||
('1', 'Désactivés'),
|
||||
('2', 'Archivés'),
|
||||
)
|
||||
|
||||
CHOICES_AFF = (
|
||||
('0', 'Utilisateurs'),
|
||||
('1', 'Machines'),
|
||||
('2', 'Factures'),
|
||||
('3', 'Bannissements'),
|
||||
('4', 'Accès à titre gracieux'),
|
||||
('5', 'Chambres'),
|
||||
('6', 'Ports'),
|
||||
('7', 'Switchs'),
|
||||
)
|
||||
|
||||
|
||||
def initial_choices(c):
|
||||
"""Return the choices that should be activated by default for a
|
||||
given set of choices"""
|
||||
return [i[0] for i in c]
|
||||
|
||||
|
||||
class SearchForm(Form):
|
||||
"""The form for a simple search"""
|
||||
q = forms.CharField(label='Search', max_length=100)
|
||||
|
||||
|
||||
class SearchFormPlus(Form):
|
||||
"""The form for an advanced search (with filters)"""
|
||||
q = forms.CharField(
|
||||
label='Search',
|
||||
max_length=100,
|
||||
required=False
|
||||
)
|
||||
u = forms.MultipleChoiceField(
|
||||
label="Filtre utilisateurs",
|
||||
required=False,
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
choices=CHOICES_USER,
|
||||
initial=initial_choices(CHOICES_USER)
|
||||
)
|
||||
a = forms.MultipleChoiceField(
|
||||
label="Filtre affichage",
|
||||
required=False,
|
||||
widget=forms.CheckboxSelectMultiple,
|
||||
choices=CHOICES_AFF,
|
||||
initial=initial_choices(CHOICES_AFF)
|
||||
)
|
||||
s = forms.DateField(
|
||||
required=False,
|
||||
label="Date de début",
|
||||
help_text='DD/MM/YYYY',
|
||||
input_formats=['%d/%m/%Y']
|
||||
)
|
||||
e = forms.DateField(
|
||||
required=False,
|
||||
help_text='DD/MM/YYYY',
|
||||
input_formats=['%d/%m/%Y'],
|
||||
label="Date de fin"
|
||||
)
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
# -*- mode: python; coding: utf-8 -*-
|
||||
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||
# se veut agnostique au réseau considéré, de manière à être installable en
|
||||
# quelques clics.
|
||||
#
|
||||
# Copyright © 2017 Gabriel Détraz
|
||||
# Copyright © 2017 Goulven Kermarec
|
||||
# Copyright © 2017 Augustin Lemesle
|
||||
#
|
||||
# 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.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models
|
||||
from django import forms
|
||||
from django.forms import Form
|
||||
from django.forms import ModelForm
|
||||
|
||||
CHOICES = (
|
||||
('0', 'Actifs'),
|
||||
('1', 'Désactivés'),
|
||||
('2', 'Archivés'),
|
||||
)
|
||||
|
||||
CHOICES2 = (
|
||||
(1, 'Active'),
|
||||
("", 'Désactivée'),
|
||||
)
|
||||
|
||||
CHOICES3 = (
|
||||
('0', 'Utilisateurs'),
|
||||
('1', 'Machines'),
|
||||
('2', 'Factures'),
|
||||
('3', 'Bannissements'),
|
||||
('4', 'Accès à titre gracieux'),
|
||||
('6', 'Switchs'),
|
||||
('5', 'Ports'),
|
||||
)
|
||||
|
||||
|
||||
class SearchForm(Form):
|
||||
search_field = forms.CharField(label = 'Search', max_length = 100)
|
||||
|
||||
class SearchFormPlus(Form):
|
||||
search_field = forms.CharField(label = 'Search', max_length = 100, required=False)
|
||||
filtre = forms.MultipleChoiceField(label="Filtre utilisateurs", required=False, widget =forms.CheckboxSelectMultiple,choices=CHOICES)
|
||||
connexion = forms.MultipleChoiceField(label="Filtre connexion", required=False, widget =forms.CheckboxSelectMultiple,choices=CHOICES2)
|
||||
affichage = forms.MultipleChoiceField(label="Filtre affichage", required=False, widget =forms.CheckboxSelectMultiple,choices=CHOICES3)
|
||||
date_deb = forms.DateField(required=False, label="Date de début", help_text='DD/MM/YYYY', input_formats=['%d/%m/%Y'])
|
||||
date_fin = forms.DateField(required=False, help_text='DD/MM/YYYY', input_formats=['%d/%m/%Y'], label="Date de fin")
|
|
@ -36,30 +36,35 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
<h2>Résultats dans les machines : </h2>
|
||||
{% include "machines/aff_machines.html" with machines_list=machines_list %}
|
||||
{% endif %}
|
||||
{% if facture_list %}
|
||||
{% if factures_list %}
|
||||
<h2>Résultats dans les factures : </h2>
|
||||
{% include "cotisations/aff_cotisations.html" with facture_list=facture_list %}
|
||||
{% include "cotisations/aff_cotisations.html" with facture_list=factures_list %}
|
||||
{% endif %}
|
||||
{% if white_list %}
|
||||
{% if whitelists_list %}
|
||||
<h2>Résultats dans les accès à titre gracieux : </h2>
|
||||
{% include "users/aff_whitelists.html" with white_list=white_list %}
|
||||
{% include "users/aff_whitelists.html" with white_list=whitelists_list %}
|
||||
{% endif %}
|
||||
{% if ban_list %}
|
||||
{% if bans_list %}
|
||||
<h2>Résultats dans les banissements : </h2>
|
||||
{% include "users/aff_bans.html" with ban_list=ban_list %}
|
||||
{% include "users/aff_bans.html" with ban_list=bans_list %}
|
||||
{% endif %}
|
||||
{% if switch_list %}
|
||||
<h2>Résultats dans les switchs : </h2>
|
||||
{% include "topologie/aff_switch.html" with switch_list=switch_list %}
|
||||
{% if rooms_list %}
|
||||
<h2>Résultats dans les chambres : </h2>
|
||||
{% include "topologie/aff_chambres.html" with room_list=rooms_list %}
|
||||
{% endif %}
|
||||
{% if port_list %}
|
||||
{% if switch_ports_list %}
|
||||
<h2>Résultats dans les ports : </h2>
|
||||
{% include "topologie/aff_port.html" with port_list=port_list %}
|
||||
{% include "topologie/aff_port.html" with port_list=switch_ports_list %}
|
||||
{% endif %}
|
||||
{% if not ban_list and not interfaces_list and not users_list and not facture_list and not white_list and not port_list and not switch_list%}
|
||||
{% if switches_list %}
|
||||
<h2>Résultats dans les switchs : </h2>
|
||||
{% include "topologie/aff_switch.html" with switch_list=switches_list %}
|
||||
{% endif %}
|
||||
{% if not users_list and not machines_list and not factures_list and not whitelists_list and not bans_list and not rooms_list and not switch_ports_list and not switches_list %}
|
||||
<h3>Aucun résultat</h3>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<h6>(Seulement les {{ max_result }} premiers résultats sont affichés dans chaque catégorie)</h6>
|
||||
{% endif %}
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
|
|
@ -28,11 +28,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
{% block title %}Recherche{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% bootstrap_form_errors searchform %}
|
||||
{% bootstrap_form_errors search_form %}
|
||||
|
||||
<form class="form" method="post">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form searchform %}
|
||||
<form class="form">
|
||||
{% bootstrap_field search_form.q %}
|
||||
{% include "buttons/multiple_checkbox_alt.html" with field=search_form.u %}
|
||||
{% include "buttons/multiple_checkbox_alt.html" with field=search_form.a %}
|
||||
{% bootstrap_field search_form.s %}
|
||||
{% bootstrap_field search_form.e %}
|
||||
{% bootstrap_button "Search" button_type="submit" icon="search" %}
|
||||
</form>
|
||||
<br />
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
"""The urls used by the search app"""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf.urls import url
|
||||
|
@ -28,5 +30,5 @@ from . import views
|
|||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.search, name='search'),
|
||||
url(r'^avance/$', views.searchp, name='searchp'),
|
||||
url(r'^advanced/$', views.searchp, name='searchp'),
|
||||
]
|
||||
|
|
381
search/views.py
381
search/views.py
|
@ -20,115 +20,326 @@
|
|||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
# App de recherche pour re2o
|
||||
# Augustin lemesle, Gabriel Détraz, Goulven Kermarec
|
||||
# Gplv2
|
||||
"""The views for the search app, responsible for finding the matches
|
||||
Augustin lemesle, Gabriel Détraz, Goulven Kermarec, Maël Kervella
|
||||
Gplv2"""
|
||||
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.template.context_processors import csrf
|
||||
from django.template import Context, RequestContext, loader
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from django.db.models import Q
|
||||
from users.models import User, Ban, Whitelist
|
||||
from machines.models import Machine, Interface
|
||||
from topologie.models import Port, Switch
|
||||
from machines.models import Machine
|
||||
from topologie.models import Port, Switch, Room
|
||||
from cotisations.models import Facture
|
||||
from search.models import SearchForm, SearchFormPlus
|
||||
from preferences.models import GeneralOption
|
||||
from search.forms import (
|
||||
SearchForm,
|
||||
SearchFormPlus,
|
||||
CHOICES_USER,
|
||||
CHOICES_AFF,
|
||||
initial_choices
|
||||
)
|
||||
from re2o.utils import SortTable
|
||||
|
||||
def form(ctx, template, request):
|
||||
c = ctx
|
||||
c.update(csrf(request))
|
||||
return render(request, template, c)
|
||||
|
||||
def search_result(search, type, request):
|
||||
date_deb = None
|
||||
date_fin = None
|
||||
states=[]
|
||||
co=[]
|
||||
aff=[]
|
||||
if(type):
|
||||
aff = search.cleaned_data['affichage']
|
||||
co = search.cleaned_data['connexion']
|
||||
states = search.cleaned_data['filtre']
|
||||
date_deb = search.cleaned_data['date_deb']
|
||||
date_fin = search.cleaned_data['date_fin']
|
||||
date_query = Q()
|
||||
if aff==[]:
|
||||
aff = ['0','1','2','3','4','5','6']
|
||||
if date_deb != None:
|
||||
date_query = date_query & Q(date__gte=date_deb)
|
||||
if date_fin != None:
|
||||
date_query = date_query & Q(date__lte=date_fin)
|
||||
search = search.cleaned_data['search_field']
|
||||
query1 = Q()
|
||||
for s in states:
|
||||
query1 = query1 | Q(state = s)
|
||||
def is_int(variable):
|
||||
""" Check if the variable can be casted to an integer """
|
||||
|
||||
connexion = []
|
||||
|
||||
recherche = {'users_list': None, 'machines_list' : [], 'facture_list' : None, 'ban_list' : None, 'white_list': None, 'port_list': None, 'switch_list': None}
|
||||
|
||||
if request.user.has_perms(('cableur',)):
|
||||
query = Q(user__pseudo__icontains = search) | Q(user__adherent__name__icontains = search) | Q(user__surname__icontains = search)
|
||||
try:
|
||||
int(variable)
|
||||
except ValueError:
|
||||
return False
|
||||
else:
|
||||
query = (Q(user__pseudo__icontains = search) | Q(user__adherent__name__icontains = search) | Q(user__surname__icontains = search)) & Q(user = request.user)
|
||||
return True
|
||||
|
||||
|
||||
for i in aff:
|
||||
if i == '0':
|
||||
query_user_list = Q(adherent__room__name__icontains = search) | Q(club__room__name__icontains = search) | Q(pseudo__icontains = search) | Q(adherent__name__icontains = search) | Q(surname__icontains = search) & query1
|
||||
if request.user.has_perms(('cableur',)):
|
||||
recherche['users_list'] = User.objects.filter(query_user_list).order_by('state', 'surname').distinct()
|
||||
else :
|
||||
recherche['users_list'] = User.objects.filter(query_user_list & Q(id=request.user.id)).order_by('state', 'surname').distinct()
|
||||
if i == '1':
|
||||
query_machine_list = Q(machine__user__pseudo__icontains = search) | Q(machine__user__adherent__name__icontains = search) | Q(machine__user__surname__icontains = search) | Q(mac_address__icontains = search) | Q(ipv4__ipv4__icontains = search) | Q(domain__name__icontains = search) | Q(domain__related_domain__name__icontains = search)
|
||||
if request.user.has_perms(('cableur',)):
|
||||
data = Interface.objects.filter(query_machine_list).distinct()
|
||||
else:
|
||||
data = Interface.objects.filter(query_machine_list & Q(machine__user__id = request.user.id)).distinct()
|
||||
for d in data:
|
||||
recherche['machines_list'].append(d.machine)
|
||||
if i == '2':
|
||||
recherche['facture_list'] = Facture.objects.filter(query & date_query).distinct()
|
||||
if i == '3':
|
||||
recherche['ban_list'] = Ban.objects.filter(query).distinct()
|
||||
if i == '4':
|
||||
recherche['white_list'] = Whitelist.objects.filter(query).distinct()
|
||||
if i == '5':
|
||||
recherche['port_list'] = Port.objects.filter(details__icontains = search).distinct()
|
||||
def get_results(query, request, filters={}):
|
||||
""" Construct the correct filters to match differents fields of some models
|
||||
with the given query according to the given filters.
|
||||
The match field are either CharField or IntegerField that will be displayed
|
||||
on the results page (else, one might not see why a result has matched the
|
||||
query). IntegerField are matched against the query only if it can be casted
|
||||
to an int."""
|
||||
|
||||
start = filters.get('s', None)
|
||||
end = filters.get('e', None)
|
||||
user_state = filters.get('u', initial_choices(CHOICES_USER))
|
||||
aff = filters.get('a', initial_choices(CHOICES_AFF))
|
||||
|
||||
options, _ = GeneralOption.objects.get_or_create()
|
||||
max_result = options.search_display_page
|
||||
|
||||
results = {
|
||||
'users_list': User.objects.none(),
|
||||
'machines_list': Machine.objects.none(),
|
||||
'factures_list': Facture.objects.none(),
|
||||
'bans_list': Ban.objects.none(),
|
||||
'whitelists_list': Whitelist.objects.none(),
|
||||
'rooms_list': Room.objects.none(),
|
||||
'switch_ports_list': Port.objects.none(),
|
||||
'switches_list': Switch.objects.none()
|
||||
}
|
||||
|
||||
# Users
|
||||
if '0' in aff:
|
||||
filter_user_list = (
|
||||
Q(
|
||||
surname__icontains=query
|
||||
) | Q(
|
||||
adherent__name__icontains=query
|
||||
) | Q(
|
||||
pseudo__icontains=query
|
||||
) | Q(
|
||||
club__room__name__icontains=query
|
||||
) | Q(
|
||||
adherent__room__name__icontains=query
|
||||
)
|
||||
) & Q(state__in=user_state)
|
||||
if not request.user.has_perms(('cableur',)):
|
||||
recherche['port_list'] = None
|
||||
if i == '6':
|
||||
recherche['switch_list'] = Switch.objects.filter(details__icontains = search).distinct()
|
||||
filter_user_list &= Q(id=request.user.id)
|
||||
results['users_list'] = User.objects.filter(filter_user_list)
|
||||
results['users_list'] = SortTable.sort(
|
||||
results['users_list'],
|
||||
request.GET.get('col'),
|
||||
request.GET.get('order'),
|
||||
SortTable.USERS_INDEX
|
||||
)
|
||||
|
||||
# Machines
|
||||
if '1' in aff:
|
||||
filter_machine_list = Q(
|
||||
name__icontains=query
|
||||
) | (
|
||||
Q(
|
||||
user__pseudo__icontains=query
|
||||
) & Q(
|
||||
user__state__in=user_state
|
||||
)
|
||||
) | Q(
|
||||
interface__domain__name__icontains=query
|
||||
) | Q(
|
||||
interface__domain__related_domain__name__icontains=query
|
||||
) | Q(
|
||||
interface__mac_address__icontains=query
|
||||
) | Q(
|
||||
interface__ipv4__ipv4__icontains=query
|
||||
)
|
||||
if not request.user.has_perms(('cableur',)):
|
||||
recherche['switch_list'] = None
|
||||
options, created = GeneralOption.objects.get_or_create()
|
||||
search_display_page = options.search_display_page
|
||||
filter_machine_list &= Q(user__id=request.user.id)
|
||||
results['machines_list'] = Machine.objects.filter(filter_machine_list)
|
||||
results['machines_list'] = SortTable.sort(
|
||||
results['machines_list'],
|
||||
request.GET.get('col'),
|
||||
request.GET.get('order'),
|
||||
SortTable.MACHINES_INDEX
|
||||
)
|
||||
|
||||
for r in recherche:
|
||||
if recherche[r] != None:
|
||||
recherche[r] = recherche[r][:search_display_page]
|
||||
# Factures
|
||||
if '2' in aff:
|
||||
filter_facture_list = Q(
|
||||
user__pseudo__icontains=query
|
||||
) & Q(
|
||||
user__state__in=user_state
|
||||
)
|
||||
if start is not None:
|
||||
filter_facture_list &= Q(date__gte=start)
|
||||
if end is not None:
|
||||
filter_facture_list &= Q(date__lte=end)
|
||||
results['factures_list'] = Facture.objects.filter(filter_facture_list)
|
||||
results['factures_list'] = SortTable.sort(
|
||||
results['factures_list'],
|
||||
request.GET.get('col'),
|
||||
request.GET.get('order'),
|
||||
SortTable.COTISATIONS_INDEX
|
||||
)
|
||||
|
||||
recherche.update({'max_result': search_display_page})
|
||||
# Bans
|
||||
if '3' in aff:
|
||||
date_filter = (
|
||||
Q(
|
||||
user__pseudo__icontains=query
|
||||
) & Q(
|
||||
user__state__in=user_state
|
||||
)
|
||||
) | Q(
|
||||
raison__icontains=query
|
||||
)
|
||||
if start is not None:
|
||||
date_filter &= (
|
||||
Q(date_start__gte=start) & Q(date_end__gte=start)
|
||||
) | (
|
||||
Q(date_start__lte=start) & Q(date_end__gte=start)
|
||||
) | (
|
||||
Q(date_start__gte=start) & Q(date_end__lte=start)
|
||||
)
|
||||
if end is not None:
|
||||
date_filter &= (
|
||||
Q(date_start__lte=end) & Q(date_end__lte=end)
|
||||
) | (
|
||||
Q(date_start__lte=end) & Q(date_end__gte=end)
|
||||
) | (
|
||||
Q(date_start__gte=end) & Q(date_end__lte=end)
|
||||
)
|
||||
results['bans_list'] = Ban.objects.filter(date_filter)
|
||||
results['bans_list'] = SortTable.sort(
|
||||
results['bans_list'],
|
||||
request.GET.get('col'),
|
||||
request.GET.get('order'),
|
||||
SortTable.USERS_INDEX_BAN
|
||||
)
|
||||
|
||||
# Whitelists
|
||||
if '4' in aff:
|
||||
date_filter = (
|
||||
Q(
|
||||
user__pseudo__icontains=query
|
||||
) & Q(
|
||||
user__state__in=user_state
|
||||
)
|
||||
) | Q(
|
||||
raison__icontains=query
|
||||
)
|
||||
if start is not None:
|
||||
date_filter &= (
|
||||
Q(date_start__gte=start) & Q(date_end__gte=start)
|
||||
) | (
|
||||
Q(date_start__lte=start) & Q(date_end__gte=start)
|
||||
) | (
|
||||
Q(date_start__gte=start) & Q(date_end__lte=start)
|
||||
)
|
||||
if end is not None:
|
||||
date_filter &= (
|
||||
Q(date_start__lte=end) & Q(date_end__lte=end)
|
||||
) | (
|
||||
Q(date_start__lte=end) & Q(date_end__gte=end)
|
||||
) | (
|
||||
Q(date_start__gte=end) & Q(date_end__lte=end)
|
||||
)
|
||||
results['whitelists_list'] = Whitelist.objects.filter(date_filter)
|
||||
results['whitelists_list'] = SortTable.sort(
|
||||
results['whitelists_list'],
|
||||
request.GET.get('col'),
|
||||
request.GET.get('order'),
|
||||
SortTable.USERS_INDEX_WHITE
|
||||
)
|
||||
|
||||
# Rooms
|
||||
if '5' in aff and request.user.has_perms(('cableur',)):
|
||||
filter_rooms_list = Q(
|
||||
details__icontains=query
|
||||
) | Q(
|
||||
name__icontains=query
|
||||
) | Q(
|
||||
port__details=query
|
||||
)
|
||||
results['rooms_list'] = Room.objects.filter(filter_rooms_list)
|
||||
results['rooms_list'] = SortTable.sort(
|
||||
results['rooms_list'],
|
||||
request.GET.get('col'),
|
||||
request.GET.get('order'),
|
||||
SortTable.TOPOLOGIE_INDEX_ROOM
|
||||
)
|
||||
|
||||
# Switch ports
|
||||
if '6' in aff and request.user.has_perms(('cableur',)):
|
||||
filter_ports_list = Q(
|
||||
room__name__icontains=query
|
||||
) | Q(
|
||||
machine_interface__domain__name__icontains=query
|
||||
) | Q(
|
||||
related__switch__switch_interface__domain__name__icontains=query
|
||||
) | Q(
|
||||
radius__icontains=query
|
||||
) | Q(
|
||||
vlan_force__name__icontains=query
|
||||
) | Q(
|
||||
details__icontains=query
|
||||
)
|
||||
if is_int(query):
|
||||
filter_ports_list |= Q(
|
||||
port=query
|
||||
)
|
||||
results['switch_ports_list'] = Port.objects.filter(filter_ports_list)
|
||||
results['switch_ports_list'] = SortTable.sort(
|
||||
results['switch_ports_list'],
|
||||
request.GET.get('col'),
|
||||
request.GET.get('order'),
|
||||
SortTable.TOPOLOGIE_INDEX_PORT
|
||||
)
|
||||
|
||||
# Switches
|
||||
if '7' in aff and request.user.has_perms(('cableur',)):
|
||||
filter_switches_list = Q(
|
||||
switch_interface__domain__name__icontains=query
|
||||
) | Q(
|
||||
switch_interface__ipv4__ipv4__icontains=query
|
||||
) | Q(
|
||||
location__icontains=query
|
||||
) | Q(
|
||||
stack__name__icontains=query
|
||||
) | Q(
|
||||
model__reference__icontains=query
|
||||
) | Q(
|
||||
model__constructor__name__icontains=query
|
||||
) | Q(
|
||||
details__icontains=query
|
||||
)
|
||||
if is_int(query):
|
||||
filter_switches_list |= Q(
|
||||
number=query
|
||||
) | Q(
|
||||
stack_member_id=query
|
||||
)
|
||||
results['switches_list'] = Switch.objects.filter(filter_switches_list)
|
||||
results['switches_list'] = SortTable.sort(
|
||||
results['switches_list'],
|
||||
request.GET.get('col'),
|
||||
request.GET.get('order'),
|
||||
SortTable.TOPOLOGIE_INDEX
|
||||
)
|
||||
|
||||
for name, val in results.items():
|
||||
results[name] = val.distinct()[:max_result]
|
||||
|
||||
results.update({'max_result': max_result})
|
||||
results.update({'search_term': query})
|
||||
|
||||
return results
|
||||
|
||||
return recherche
|
||||
|
||||
@login_required
|
||||
def search(request):
|
||||
search = SearchForm(request.POST or None)
|
||||
if search.is_valid():
|
||||
return form(search_result(search, False, request), 'search/index.html',request)
|
||||
return form({'searchform' : search}, 'search/search.html', request)
|
||||
""" La page de recherche standard """
|
||||
search_form = SearchForm(request.GET or None)
|
||||
if search_form.is_valid():
|
||||
return render(
|
||||
request,
|
||||
'search/index.html',
|
||||
get_results(
|
||||
search_form.cleaned_data.get('q', ''),
|
||||
request,
|
||||
search_form.cleaned_data
|
||||
)
|
||||
)
|
||||
return render(request, 'search/search.html', {'search_form': search_form})
|
||||
|
||||
|
||||
@login_required
|
||||
def searchp(request):
|
||||
search = SearchFormPlus(request.POST or None)
|
||||
if search.is_valid():
|
||||
return form(search_result(search, True, request), 'search/index.html',request)
|
||||
return form({'searchform' : search}, 'search/search.html', request)
|
||||
""" La page de recherche avancée """
|
||||
search_form = SearchFormPlus(request.GET or None)
|
||||
if search_form.is_valid():
|
||||
return render(
|
||||
request,
|
||||
'search/index.html',
|
||||
get_results(
|
||||
search_form.cleaned_data.get('q', ''),
|
||||
request,
|
||||
search_form.cleaned_data
|
||||
)
|
||||
)
|
||||
return render(request, 'search/search.html', {'search_form': search_form})
|
||||
|
|
|
@ -73,10 +73,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
{% endif %}
|
||||
</ul>
|
||||
<div class="col-sm-3 col-md-3 navbar-right">
|
||||
<form action="{% url "search:search"%}" method="POST" class="navbar-form" role="search">
|
||||
{% csrf_token %}
|
||||
<form action="{% url "search:search"%}" class="navbar-form" role="search">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="Search" name="search_field" id="search-term">
|
||||
<input type="text" class="form-control" placeholder="Search" name="q" id="search-term" {% if search_term %}value="{{ search_term }}"{% endif %}>
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
|
||||
<a href="{% url "search:searchp" %}" class="btn btn-default" role="button"><i class="glyphicon glyphicon-plus"></i></a>
|
||||
|
|
40
templates/buttons/multiple_checkbox_alt.html
Normal file
40
templates/buttons/multiple_checkbox_alt.html
Normal file
|
@ -0,0 +1,40 @@
|
|||
{% comment %}
|
||||
Re2o est un logiciel d'administration développé initiallement au rezometz. Il
|
||||
se veut agnostique au réseau considéré, de manière à être installable en
|
||||
quelques clics.
|
||||
|
||||
Copyright © 2017 Gabriel Détraz
|
||||
Copyright © 2017 Goulven Kermarec
|
||||
Copyright © 2017 Augustin Lemesle
|
||||
|
||||
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.
|
||||
{% endcomment %}
|
||||
|
||||
<div class="form-group {% if field.form.errors %}{% if field.errors %}has-error{% else %}has-success{% endif %}{% endif %}">
|
||||
<label class="control-label" for="{{ field.id_for_label }}">
|
||||
{{ field.label }}
|
||||
</label>
|
||||
<div id="{{ field.auto_id }}" data-toggle="buttons">
|
||||
{% for val in field.field.choices %}
|
||||
<label for="id_u_{{ val.0 }}" class="btn btn-default{% if val.0 in field.initial %} active{% endif %}">
|
||||
<input {% if val.0 in field.initial %}checked="checked" {% endif %}class="" id="id_u_{{ val.0 }}" name="{{ field.name }}" title="" type="checkbox" value="{{ val.0 }}" /> {{ val.1 }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% for error in field.errors %}
|
||||
<div class="help-block">{{ error }}</div>
|
||||
{% endfor %}
|
||||
<div class="help-block">{{ field.help_text }}</div>
|
||||
</div>
|
Loading…
Reference in a new issue