Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
re2o
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Nounous
re2o
Commits
54fad989
Commit
54fad989
authored
Oct 14, 2017
by
chirac
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Docstrings et pep8 sur logs
parent
77ce677c
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
215 additions
and
132 deletions
+215
-132
logs/urls.py
logs/urls.py
+7
-2
logs/views.py
logs/views.py
+208
-130
No files found.
logs/urls.py
View file @
54fad989
...
...
@@ -19,7 +19,10 @@
# 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.
"""
Urls de l'application logs, pointe vers les fonctions de views.
Inclu dans le re2o.urls
"""
from
__future__
import
unicode_literals
from
django.conf.urls
import
url
...
...
@@ -29,7 +32,9 @@ from . import views
urlpatterns
=
[
url
(
r
'^$'
,
views
.
index
,
name
=
'index'
),
url
(
r
'^stats_logs$'
,
views
.
stats_logs
,
name
=
'stats-logs'
),
url
(
r
'^revert_action/(?P<revision_id>[0-9]+)$'
,
views
.
revert_action
,
name
=
'revert-action'
),
url
(
r
'^revert_action/(?P<revision_id>[0-9]+)$'
,
views
.
revert_action
,
name
=
'revert-action'
),
url
(
r
'^stats_general/$'
,
views
.
stats_general
,
name
=
'stats-general'
),
url
(
r
'^stats_models/$'
,
views
.
stats_models
,
name
=
'stats-models'
),
url
(
r
'^stats_users/$'
,
views
.
stats_users
,
name
=
'stats-users'
),
...
...
logs/views.py
View file @
54fad989
...
...
@@ -23,62 +23,68 @@
# App de gestion des statistiques pour re2o
# Gabriel Détraz
# Gplv2
"""
Vues des logs et statistiques générales.
La vue index générale affiche une selection des dernières actions,
classées selon l'importance, avec date, et user formatés.
Stats_logs renvoie l'ensemble des logs.
Les autres vues sont thématiques, ensemble des statistiques et du
nombre d'objets par models, nombre d'actions par user, etc
"""
from
__future__
import
unicode_literals
from
django.http
import
HttpResponse
from
django.shortcuts
import
render
,
redirect
from
django.shortcuts
import
get_object_or_404
from
django.template.context_processors
import
csrf
from
django.core.paginator
import
Paginator
,
EmptyPage
,
PageNotAnInteger
from
django.template
import
Context
,
RequestContext
,
loader
from
django.contrib
import
messages
from
django.contrib.auth.decorators
import
login_required
,
permission_required
from
django.db.models
import
ProtectedError
from
django.forms
import
ValidationError
from
django.db
import
transaction
from
django.db.models
import
Count
from
reversion.models
import
Revision
from
reversion.models
import
Version
,
ContentType
from
users.models
import
User
,
ServiceUser
,
Right
,
School
,
ListRight
,
ListShell
,
Ban
,
Whitelist
from
users.models
import
all_has_access
,
all_whitelisted
,
all_baned
,
all_adherent
from
cotisations.models
import
Facture
,
Vente
,
Article
,
Banque
,
Paiement
,
Cotisation
from
machines.models
import
Machine
,
MachineType
,
IpType
,
Extension
,
Interface
,
Domain
,
IpList
from
machines.views
import
all_active_assigned_interfaces_count
,
all_active_interfaces_count
from
users.models
import
User
,
ServiceUser
,
Right
,
School
,
ListRight
,
ListShell
from
users.models
import
Ban
,
Whitelist
,
all_has_access
from
users.models
import
all_whitelisted
,
all_baned
,
all_adherent
from
cotisations.models
import
Facture
,
Vente
,
Article
,
Banque
,
Paiement
from
cotisations.models
import
Cotisation
from
machines.models
import
Machine
,
MachineType
,
IpType
,
Extension
,
Interface
from
machines.models
import
Domain
,
IpList
from
machines.views
import
all_active_assigned_interfaces_count
from
machines.views
import
all_active_interfaces_count
from
topologie.models
import
Switch
,
Port
,
Room
from
preferences.models
import
GeneralOption
from
re2o.views
import
form
from
django.utils
import
timezone
from
dateutil.relativedelta
import
relativedelta
STATS_DICT
=
{
0
:
[
"Tout"
,
36
],
1
:
[
"1 mois"
,
1
],
2
:
[
"2 mois"
,
2
],
3
:
[
"6 mois"
,
6
],
4
:
[
"1 an"
,
12
],
5
:
[
"2 an"
,
24
],
0
:
[
"Tout"
,
36
],
1
:
[
"1 mois"
,
1
],
2
:
[
"2 mois"
,
2
],
3
:
[
"6 mois"
,
6
],
4
:
[
"1 an"
,
12
],
5
:
[
"2 an"
,
24
],
}
def
form
(
ctx
,
template
,
request
):
c
=
ctx
c
.
update
(
csrf
(
request
))
return
render
(
request
,
template
,
c
)
@
login_required
@
permission_required
(
'cableur'
)
def
index
(
request
):
options
,
created
=
GeneralOption
.
objects
.
get_or_create
()
"""Affiche les logs affinés, date reformatées, selectionne
les event importants (ajout de droits, ajout de ban/whitelist)"""
options
,
_created
=
GeneralOption
.
objects
.
get_or_create
()
pagination_number
=
options
.
pagination_number
# The types of content kept for display
content_type_filter
=
[
'ban'
,
'whitelist'
,
'vente'
,
'interface'
,
'user'
]
content_type_filter
=
[
'ban'
,
'whitelist'
,
'vente'
,
'interface'
,
'user'
]
# Select only wanted versions
versions
=
Version
.
objects
.
filter
(
content_type__in
=
ContentType
.
objects
.
filter
(
model__in
=
content_type_filter
)).
order_by
(
'revision__date_created'
).
reverse
().
select_related
(
'revision'
)
versions
=
Version
.
objects
.
filter
(
content_type__in
=
ContentType
.
objects
.
filter
(
model__in
=
content_type_filter
)
).
order_by
(
'revision__date_created'
).
reverse
().
select_related
(
'revision'
)
paginator
=
Paginator
(
versions
,
pagination_number
)
page
=
request
.
GET
.
get
(
'page'
)
try
:
...
...
@@ -87,7 +93,7 @@ def index(request):
# If page is not an integer, deliver first page.
versions
=
paginator
.
page
(
1
)
except
EmptyPage
:
# If page is out of range (e.g. 9999), deliver last page of results.
# If page is out of range (e.g. 9999), deliver last page of results.
versions
=
paginator
.
page
(
paginator
.
num_pages
)
# Force to have a list instead of QuerySet
...
...
@@ -95,30 +101,38 @@ def index(request):
# Items to remove later because invalid
to_remove
=
[]
# Parse every item (max = pagination_number)
for
i
in
range
(
len
(
versions
.
object_list
)
):
if
versions
.
object_list
[
i
].
object
:
v
=
versions
.
object_list
[
i
]
for
i
in
range
(
len
(
versions
.
object_list
)
):
if
versions
.
object_list
[
i
].
object
:
v
ersion
=
versions
.
object_list
[
i
]
versions
.
object_list
[
i
]
=
{
'rev_id'
:
v
.
revision
.
id
,
'comment'
:
v
.
revision
.
comment
,
'datetime'
:
v
.
revision
.
date_created
.
strftime
(
'%d/%m/%y %H:%M:%S'
),
'username'
:
v
.
revision
.
user
.
get_username
()
if
v
.
revision
.
user
else
'?'
,
'user_id'
:
v
.
revision
.
user_id
,
'version'
:
v
}
else
:
to_remove
.
insert
(
0
,
i
)
'rev_id'
:
version
.
revision
.
id
,
'comment'
:
version
.
revision
.
comment
,
'datetime'
:
version
.
revision
.
date_created
.
strftime
(
'%d/%m/%y %H:%M:%S'
),
'username'
:
version
.
revision
.
user
.
get_username
()
if
version
.
revision
.
user
else
'?'
,
'user_id'
:
version
.
revision
.
user_id
,
'version'
:
version
}
else
:
to_remove
.
insert
(
0
,
i
)
# Remove all tagged invalid items
for
i
in
to_remove
:
for
i
in
to_remove
:
versions
.
object_list
.
pop
(
i
)
return
render
(
request
,
'logs/index.html'
,
{
'versions_list'
:
versions
})
@
login_required
@
permission_required
(
'cableur'
)
def
stats_logs
(
request
):
options
,
created
=
GeneralOption
.
objects
.
get_or_create
()
"""Affiche l'ensemble des logs et des modifications sur les objets,
classés par date croissante, en vrac"""
options
,
_created
=
GeneralOption
.
objects
.
get_or_create
()
pagination_number
=
options
.
pagination_number
revisions
=
Revision
.
objects
.
all
().
order_by
(
'date_created'
).
reverse
().
select_related
(
'user'
).
prefetch_related
(
'version_set__object'
)
revisions
=
Revision
.
objects
.
all
().
order_by
(
'date_created'
)
\
.
reverse
().
select_related
(
'user'
)
\
.
prefetch_related
(
'version_set__object'
)
paginator
=
Paginator
(
revisions
,
pagination_number
)
page
=
request
.
GET
.
get
(
'page'
)
try
:
...
...
@@ -127,9 +141,12 @@ def stats_logs(request):
# If page is not an integer, deliver first page.
revisions
=
paginator
.
page
(
1
)
except
EmptyPage
:
# If page is out of range (e.g. 9999), deliver last page of results.
# If page is out of range (e.g. 9999), deliver last page of results.
revisions
=
paginator
.
page
(
paginator
.
num_pages
)
return
render
(
request
,
'logs/stats_logs.html'
,
{
'revisions_list'
:
revisions
})
return
render
(
request
,
'logs/stats_logs.html'
,
{
'revisions_list'
:
revisions
})
@
login_required
@
permission_required
(
'bureau'
)
...
...
@@ -138,121 +155,182 @@ def revert_action(request, revision_id):
try
:
revision
=
Revision
.
objects
.
get
(
id
=
revision_id
)
except
Revision
.
DoesNotExist
:
messages
.
error
(
request
,
u
"Revision inexistante"
)
messages
.
error
(
request
,
u
"Revision inexistante"
)
if
request
.
method
==
"POST"
:
revision
.
revert
()
messages
.
success
(
request
,
"L'action a été supprimée"
)
return
redirect
(
"/logs/"
)
return
form
({
'objet'
:
revision
,
'objet_name'
:
revision
.
__class__
.
__name__
},
'logs/delete.html'
,
request
)
return
form
({
'objet'
:
revision
,
'objet_name'
:
revision
.
__class__
.
__name__
},
'logs/delete.html'
,
request
)
@
login_required
@
permission_required
(
'cableur'
)
def
stats_general
(
request
):
all_active_users
=
User
.
objects
.
filter
(
state
=
User
.
STATE_ACTIVE
)
ip
=
dict
()
"""Statistiques générales affinées sur les ip, activées, utilisées par
range, et les statistiques générales sur les users : users actifs,
cotisants, activés, archivés, etc"""
ip_dict
=
dict
()
for
ip_range
in
IpType
.
objects
.
all
():
all_ip
=
IpList
.
objects
.
filter
(
ip_type
=
ip_range
)
used_ip
=
Interface
.
objects
.
filter
(
ipv4__in
=
all_ip
).
count
()
active_ip
=
all_active_assigned_interfaces_count
().
filter
(
ipv4__in
=
IpList
.
objects
.
filter
(
ip_type
=
ip_range
)).
count
()
ip
[
ip_range
]
=
[
ip_range
,
all_ip
.
count
(),
used_ip
,
active_ip
,
all_ip
.
count
()
-
used_ip
]
active_ip
=
all_active_assigned_interfaces_count
().
filter
(
ipv4__in
=
IpList
.
objects
.
filter
(
ip_type
=
ip_range
)
).
count
()
ip_dict
[
ip_range
]
=
[
ip_range
,
all_ip
.
count
(),
used_ip
,
active_ip
,
all_ip
.
count
()
-
used_ip
]
stats
=
[
[[
"Categorie"
,
"Nombre d'utilisateurs"
],
{
'active_users'
:
[
"Users actifs"
,
User
.
objects
.
filter
(
state
=
User
.
STATE_ACTIVE
).
count
()],
'inactive_users'
:
[
"Users désactivés"
,
User
.
objects
.
filter
(
state
=
User
.
STATE_DISABLED
).
count
()],
'archive_users'
:
[
"Users archivés"
,
User
.
objects
.
filter
(
state
=
User
.
STATE_ARCHIVE
).
count
()],
'adherent_users'
:
[
"Adhérents à l'association"
,
all_adherent
().
count
()],
'connexion_users'
:
[
"Utilisateurs bénéficiant d'une connexion"
,
all_has_access
().
count
()],
'ban_users'
:
[
"Utilisateurs bannis"
,
all_baned
().
count
()],
'whitelisted_user'
:
[
"Utilisateurs bénéficiant d'une connexion gracieuse"
,
all_whitelisted
().
count
()],
'actives_interfaces'
:
[
"Interfaces actives (ayant accès au reseau)"
,
all_active_interfaces_count
().
count
()],
'actives_assigned_interfaces'
:
[
"Interfaces actives et assignées ipv4"
,
all_active_assigned_interfaces_count
().
count
()]
}],
[[
"Range d'ip"
,
"Nombre d'ip totales"
,
"Ip assignées"
,
"Ip assignées à une machine active"
,
"Ip non assignées"
]
,
ip
]
]
[[
"Categorie"
,
"Nombre d'utilisateurs"
],
{
'active_users'
:
[
"Users actifs"
,
User
.
objects
.
filter
(
state
=
User
.
STATE_ACTIVE
).
count
()],
'inactive_users'
:
[
"Users désactivés"
,
User
.
objects
.
filter
(
state
=
User
.
STATE_DISABLED
).
count
()],
'archive_users'
:
[
"Users archivés"
,
User
.
objects
.
filter
(
state
=
User
.
STATE_ARCHIVE
).
count
()],
'adherent_users'
:
[
"Adhérents à l'association"
,
all_adherent
().
count
()],
'connexion_users'
:
[
"Utilisateurs bénéficiant d'une connexion"
,
all_has_access
().
count
()],
'ban_users'
:
[
"Utilisateurs bannis"
,
all_baned
().
count
()],
'whitelisted_user'
:
[
"Utilisateurs bénéficiant d'une connexion gracieuse"
,
all_whitelisted
().
count
()],
'actives_interfaces'
:
[
"Interfaces actives (ayant accès au reseau)"
,
all_active_interfaces_count
().
count
()],
'actives_assigned_interfaces'
:
[
"Interfaces actives et assignées ipv4"
,
all_active_assigned_interfaces_count
().
count
()]
}],
[[
"Range d'ip"
,
"Nombre d'ip totales"
,
"Ip assignées"
,
"Ip assignées à une machine active"
,
"Ip non assignées"
],
ip_dict
]
]
return
render
(
request
,
'logs/stats_general.html'
,
{
'stats_list'
:
stats
})
@
login_required
@
permission_required
(
'cableur'
)
def
stats_models
(
request
):
all_active_users
=
User
.
objects
.
filter
(
state
=
User
.
STATE_ACTIVE
)
"""Statistiques générales, affiche les comptages par models:
nombre d'users, d'écoles, de droits, de bannissements,
de factures, de ventes, de banque, de machines, etc"""
stats
=
{
'Users'
:
{
'users'
:
[
User
.
PRETTY_NAME
,
User
.
objects
.
count
()],
'serviceuser'
:
[
ServiceUser
.
PRETTY_NAME
,
ServiceUser
.
objects
.
count
()],
'right'
:
[
Right
.
PRETTY_NAME
,
Right
.
objects
.
count
()],
'school'
:
[
School
.
PRETTY_NAME
,
School
.
objects
.
count
()],
'listright'
:
[
ListRight
.
PRETTY_NAME
,
ListRight
.
objects
.
count
()],
'listshell'
:
[
ListShell
.
PRETTY_NAME
,
ListShell
.
objects
.
count
()],
'ban'
:
[
Ban
.
PRETTY_NAME
,
Ban
.
objects
.
count
()],
'whitelist'
:
[
Whitelist
.
PRETTY_NAME
,
Whitelist
.
objects
.
count
()]
},
'Cotisations'
:
{
'factures'
:
[
Facture
.
PRETTY_NAME
,
Facture
.
objects
.
count
()],
'vente'
:
[
Vente
.
PRETTY_NAME
,
Vente
.
objects
.
count
()],
'cotisation'
:
[
Cotisation
.
PRETTY_NAME
,
Cotisation
.
objects
.
count
()],
'article'
:
[
Article
.
PRETTY_NAME
,
Article
.
objects
.
count
()],
'banque'
:
[
Banque
.
PRETTY_NAME
,
Banque
.
objects
.
count
()],
'cotisation'
:
[
Cotisation
.
PRETTY_NAME
,
Cotisation
.
objects
.
count
()],
},
'Machines'
:
{
'machine'
:
[
Machine
.
PRETTY_NAME
,
Machine
.
objects
.
count
()],
'typemachine'
:
[
MachineType
.
PRETTY_NAME
,
MachineType
.
objects
.
count
()],
'typeip'
:
[
IpType
.
PRETTY_NAME
,
IpType
.
objects
.
count
()],
'extension'
:
[
Extension
.
PRETTY_NAME
,
Extension
.
objects
.
count
()],
'interface'
:
[
Interface
.
PRETTY_NAME
,
Interface
.
objects
.
count
()],
'alias'
:
[
Domain
.
PRETTY_NAME
,
Domain
.
objects
.
exclude
(
cname
=
None
).
count
()],
'iplist'
:
[
IpList
.
PRETTY_NAME
,
IpList
.
objects
.
count
()],
},
'Topologie'
:
{
'switch'
:
[
Switch
.
PRETTY_NAME
,
Switch
.
objects
.
count
()],
'port'
:
[
Port
.
PRETTY_NAME
,
Port
.
objects
.
count
()],
'chambre'
:
[
Room
.
PRETTY_NAME
,
Room
.
objects
.
count
()],
},
'Actions effectuées sur la base'
:
{
'revision'
:
[
"Nombre d'actions"
,
Revision
.
objects
.
count
()],
},
'Users'
:
{
'users'
:
[
User
.
PRETTY_NAME
,
User
.
objects
.
count
()],
'serviceuser'
:
[
ServiceUser
.
PRETTY_NAME
,
ServiceUser
.
objects
.
count
()],
'right'
:
[
Right
.
PRETTY_NAME
,
Right
.
objects
.
count
()],
'school'
:
[
School
.
PRETTY_NAME
,
School
.
objects
.
count
()],
'listright'
:
[
ListRight
.
PRETTY_NAME
,
ListRight
.
objects
.
count
()],
'listshell'
:
[
ListShell
.
PRETTY_NAME
,
ListShell
.
objects
.
count
()],
'ban'
:
[
Ban
.
PRETTY_NAME
,
Ban
.
objects
.
count
()],
'whitelist'
:
[
Whitelist
.
PRETTY_NAME
,
Whitelist
.
objects
.
count
()]
},
'Cotisations'
:
{
'factures'
:
[
Facture
.
PRETTY_NAME
,
Facture
.
objects
.
count
()],
'vente'
:
[
Vente
.
PRETTY_NAME
,
Vente
.
objects
.
count
()],
'cotisation'
:
[
Cotisation
.
PRETTY_NAME
,
Cotisation
.
objects
.
count
()],
'article'
:
[
Article
.
PRETTY_NAME
,
Article
.
objects
.
count
()],
'banque'
:
[
Banque
.
PRETTY_NAME
,
Banque
.
objects
.
count
()],
},
'Machines'
:
{
'machine'
:
[
Machine
.
PRETTY_NAME
,
Machine
.
objects
.
count
()],
'typemachine'
:
[
MachineType
.
PRETTY_NAME
,
MachineType
.
objects
.
count
()],
'typeip'
:
[
IpType
.
PRETTY_NAME
,
IpType
.
objects
.
count
()],
'extension'
:
[
Extension
.
PRETTY_NAME
,
Extension
.
objects
.
count
()],
'interface'
:
[
Interface
.
PRETTY_NAME
,
Interface
.
objects
.
count
()],
'alias'
:
[
Domain
.
PRETTY_NAME
,
Domain
.
objects
.
exclude
(
cname
=
None
).
count
()],
'iplist'
:
[
IpList
.
PRETTY_NAME
,
IpList
.
objects
.
count
()],
},
'Topologie'
:
{
'switch'
:
[
Switch
.
PRETTY_NAME
,
Switch
.
objects
.
count
()],
'port'
:
[
Port
.
PRETTY_NAME
,
Port
.
objects
.
count
()],
'chambre'
:
[
Room
.
PRETTY_NAME
,
Room
.
objects
.
count
()],
},
'Actions effectuées sur la base'
:
{
'revision'
:
[
"Nombre d'actions"
,
Revision
.
objects
.
count
()],
},
}
return
render
(
request
,
'logs/stats_models.html'
,
{
'stats_list'
:
stats
})
return
render
(
request
,
'logs/stats_models.html'
,
{
'stats_list'
:
stats
})
@
login_required
@
permission_required
(
'cableur'
)
def
stats_users
(
request
):
"""Affiche les statistiques base de données aggrégées par user :
nombre de machines par user, d'etablissements par user,
de moyens de paiements par user, de banque par user,
de bannissement par user, etc"""
onglet
=
request
.
GET
.
get
(
'onglet'
)
try
:
search_field
=
STATS_DICT
[
onglet
]
except
:
search_field
=
STATS_DICT
[
0
]
_
search_field
=
STATS_DICT
[
onglet
]
except
KeyError
:
_
search_field
=
STATS_DICT
[
0
]
onglet
=
0
start_date
=
timezone
.
now
()
+
relativedelta
(
months
=-
search_field
[
1
])
stats
=
{
'Utilisateur'
:
{
'Machines'
:
User
.
objects
.
annotate
(
num
=
Count
(
'machine'
)).
order_by
(
'-num'
)[:
10
],
'Facture'
:
User
.
objects
.
annotate
(
num
=
Count
(
'facture'
)).
order_by
(
'-num'
)[:
10
],
'Bannissement'
:
User
.
objects
.
annotate
(
num
=
Count
(
'ban'
)).
order_by
(
'-num'
)[:
10
],
'Accès gracieux'
:
User
.
objects
.
annotate
(
num
=
Count
(
'whitelist'
)).
order_by
(
'-num'
)[:
10
],
'Droits'
:
User
.
objects
.
annotate
(
num
=
Count
(
'right'
)).
order_by
(
'-num'
)[:
10
],
},
'Etablissement'
:
{
'Utilisateur'
:
School
.
objects
.
annotate
(
num
=
Count
(
'user'
)).
order_by
(
'-num'
)[:
10
],
},
'Moyen de paiement'
:
{
'Utilisateur'
:
Paiement
.
objects
.
annotate
(
num
=
Count
(
'facture'
)).
order_by
(
'-num'
)[:
10
],
},
'Banque'
:
{
'Utilisateur'
:
Banque
.
objects
.
annotate
(
num
=
Count
(
'facture'
)).
order_by
(
'-num'
)[:
10
],
},
'Utilisateur'
:
{
'Machines'
:
User
.
objects
.
annotate
(
num
=
Count
(
'machine'
)
).
order_by
(
'-num'
)[:
10
],
'Facture'
:
User
.
objects
.
annotate
(
num
=
Count
(
'facture'
)
).
order_by
(
'-num'
)[:
10
],
'Bannissement'
:
User
.
objects
.
annotate
(
num
=
Count
(
'ban'
)
).
order_by
(
'-num'
)[:
10
],
'Accès gracieux'
:
User
.
objects
.
annotate
(
num
=
Count
(
'whitelist'
)
).
order_by
(
'-num'
)[:
10
],
'Droits'
:
User
.
objects
.
annotate
(
num
=
Count
(
'right'
)
).
order_by
(
'-num'
)[:
10
],
},
'Etablissement'
:
{
'Utilisateur'
:
School
.
objects
.
annotate
(
num
=
Count
(
'user'
)
).
order_by
(
'-num'
)[:
10
],
},
'Moyen de paiement'
:
{
'Utilisateur'
:
Paiement
.
objects
.
annotate
(
num
=
Count
(
'facture'
)
).
order_by
(
'-num'
)[:
10
],
},
'Banque'
:
{
'Utilisateur'
:
Banque
.
objects
.
annotate
(
num
=
Count
(
'facture'
)
).
order_by
(
'-num'
)[:
10
],
},
}
return
render
(
request
,
'logs/stats_users.html'
,
{
'stats_list'
:
stats
,
'stats_dict'
:
STATS_DICT
,
'active_field'
:
onglet
})
return
render
(
request
,
'logs/stats_users.html'
,
{
'stats_list'
:
stats
,
'stats_dict'
:
STATS_DICT
,
'active_field'
:
onglet
})
@
login_required
@
permission_required
(
'cableur'
)
def
stats_actions
(
request
):
onglet
=
request
.
GET
.
get
(
'onglet'
)
"""Vue qui affiche les statistiques de modifications d'objets par
utilisateurs.
Affiche le nombre de modifications aggrégées par utilisateurs"""
stats
=
{
'Utilisateur'
:
{
'Action'
:
User
.
objects
.
annotate
(
num
=
Count
(
'revision'
)).
order_by
(
'-num'
)[:
40
],
},
'Utilisateur'
:
{
'Action'
:
User
.
objects
.
annotate
(
num
=
Count
(
'revision'
)
).
order_by
(
'-num'
)[:
40
],
},
}
return
render
(
request
,
'logs/stats_users.html'
,
{
'stats_list'
:
stats
})
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment