mirror of https://github.com/interlegis/sapl.git
Edward Ribeiro
2 years ago
10 changed files with 285 additions and 11 deletions
@ -0,0 +1,38 @@ |
|||
import json |
|||
import logging |
|||
|
|||
from django.core.management.base import BaseCommand |
|||
from sapl.base.models import AuditLog |
|||
|
|||
logger = logging.getLogger(__name__) |
|||
|
|||
|
|||
class Command(BaseCommand): |
|||
def handle(self, **options): |
|||
print("Backfilling AuditLog JSON Field...") |
|||
logs = AuditLog.objects.filter(data__isnull=True) |
|||
error_counter = 0 |
|||
if logs: |
|||
update_list = [] |
|||
for log in logs: |
|||
try: |
|||
obj = log.object[1:-1] \ |
|||
if log.object.startswith('[') else log.object |
|||
data = json.loads(obj) |
|||
log.data = data |
|||
except Exception as e: |
|||
error_counter += 1 |
|||
logging.error(e) |
|||
log.data = None |
|||
else: |
|||
update_list.append(log) |
|||
if len(update_list) == 1000: |
|||
AuditLog.objects.bulk_update(update_list, ['data']) |
|||
update_list = [] |
|||
if update_list: |
|||
AuditLog.objects.bulk_update(update_list, ['data']) |
|||
print(f"Logs backfilled: {len(logs) - error_counter}") |
|||
print(f"Logs with errors: {error_counter}") |
|||
print("Finished backfilling") |
|||
|
|||
|
@ -0,0 +1,23 @@ |
|||
# Generated by Django 2.2.28 on 2022-11-18 16:30 |
|||
|
|||
import django.contrib.postgres.fields.jsonb |
|||
from django.db import migrations |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('base', '0055_appconfig_mostrar_voto'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterModelOptions( |
|||
name='auditlog', |
|||
options={'ordering': ('-id', '-timestamp'), 'verbose_name': 'AuditLog', 'verbose_name_plural': 'AuditLogs'}, |
|||
), |
|||
migrations.AddField( |
|||
model_name='auditlog', |
|||
name='data', |
|||
field=django.contrib.postgres.fields.jsonb.JSONField(null=True, verbose_name='data'), |
|||
), |
|||
] |
@ -0,0 +1,89 @@ |
|||
{% extends "crud/list.html" %} |
|||
{% load i18n %} |
|||
{% load tz %} |
|||
{% load crispy_forms_tags staticfiles %} |
|||
|
|||
{% block head_extra_css %} |
|||
created { |
|||
background-color: green; |
|||
color: #FFF; |
|||
} |
|||
|
|||
deleted { |
|||
background-color: red; |
|||
color: #FFF; |
|||
} |
|||
{% endblock head_extra_css %} |
|||
|
|||
{% block base_content %} |
|||
{% crispy filter.form %} |
|||
<br> |
|||
{% if numero_res > 0 %} |
|||
{% if numero_res == 1 %} |
|||
<h3>Foi encontrado {{ numero_res }} resultado</h3> |
|||
{% else %} |
|||
<h3>Foram encontrados {{ numero_res }} resultados</h3> |
|||
{% endif %} |
|||
<table class="table table-striped table-hover"> |
|||
<thead> |
|||
<tr> |
|||
<th>Data/Hora</th> |
|||
<th>Usuário</th> |
|||
<th>Operação</th> |
|||
<th>Objeto</th> |
|||
<th>Id</th> |
|||
<th>Campos</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
{% for obj in page_obj %} |
|||
<tr class="background:{%if obj.operation == 'D' %}red{%else%}lightgray{%endif%}"> |
|||
<td>{{ obj.timestamp|localtime|date:"d/m/Y, H:i:s" }}</td> |
|||
<td>{{ obj.username|default:"Não informado" }}</td> |
|||
<td>{{ obj.operation }}</td> |
|||
<td>{{ obj.model_name }}</td> |
|||
<td>{{obj.data.pk}}</td> |
|||
<td> |
|||
<strong>Campos ({{obj.data.fields|length}})</strong><br/> |
|||
<hr/> |
|||
{% for key, value in obj.data.fields.items %} |
|||
<ul> |
|||
<li> |
|||
{{key}}: |
|||
{% if key == "password" %}*********{%else%}{{value|default_if_none:""}}{%endif%}<br/> |
|||
</li> |
|||
</ul> |
|||
{% if forloop.counter == 10 %} |
|||
<div id="{{obj.id}}" style="display:none;"> |
|||
{%endif%} |
|||
{% if forloop.last and forloop.counter > 10 %} |
|||
</div> |
|||
<input class="btn btn-primary btn-sm" type="button" value="Expandir/Colapsar" onclick="toggleDetails({{obj.id}})"/> |
|||
{% endif %} |
|||
{% endfor %} |
|||
</td> |
|||
</tr> |
|||
{% endfor %} |
|||
</tbody> |
|||
</table> |
|||
{% else %} |
|||
<font size="4"><p align="center">{{ NO_ENTRIES_MSG }}</p></font> |
|||
{% endif %} |
|||
<br/> |
|||
{% include 'paginacao.html'%} |
|||
<br /><br /><br /> |
|||
{% endblock base_content %} |
|||
{% block extra_js %} |
|||
<script language="Javascript"> |
|||
function toggleDetails(id) { |
|||
let curr = document.getElementById(id); |
|||
if (curr.style.display == "none") { |
|||
document.getElementById(id).style.display = "block"; |
|||
} |
|||
else { |
|||
document.getElementById(id).style.display = "none"; |
|||
} |
|||
|
|||
} |
|||
</script> |
|||
{% endblock extra_js %} |
Loading…
Reference in new issue