mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 03:56:53 -06:00
Closes #2292: Remove the deprecated UserAction model
This commit is contained in:
parent
980d62d579
commit
5f66710fcd
@ -1,13 +1,8 @@
|
||||
from django import forms
|
||||
from django.contrib import admin
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from utilities.forms import LaxURLField
|
||||
from .constants import OBJECTCHANGE_ACTION_CREATE, OBJECTCHANGE_ACTION_DELETE, OBJECTCHANGE_ACTION_UPDATE
|
||||
from .models import (
|
||||
ConfigContext, CustomField, CustomFieldChoice, Graph, ExportTemplate, ObjectChange, TopologyMap, UserAction,
|
||||
Webhook,
|
||||
)
|
||||
from .models import CustomField, CustomFieldChoice, Graph, ExportTemplate, TopologyMap, Webhook
|
||||
|
||||
|
||||
def order_content_types(field):
|
||||
@ -123,16 +118,3 @@ class TopologyMapAdmin(admin.ModelAdmin):
|
||||
prepopulated_fields = {
|
||||
'slug': ['name'],
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# User actions
|
||||
#
|
||||
|
||||
@admin.register(UserAction)
|
||||
class UserActionAdmin(admin.ModelAdmin):
|
||||
actions = None
|
||||
list_display = ['user', 'action', 'content_type', 'object_id', '_message']
|
||||
|
||||
def _message(self, obj):
|
||||
return mark_safe(obj.message)
|
||||
|
@ -8,7 +8,7 @@ from dcim.api.serializers import (
|
||||
)
|
||||
from dcim.models import Device, DeviceRole, Platform, Rack, Region, Site
|
||||
from extras.models import (
|
||||
ConfigContext, ExportTemplate, Graph, ImageAttachment, ObjectChange, ReportResult, TopologyMap, UserAction,
|
||||
ConfigContext, ExportTemplate, Graph, ImageAttachment, ObjectChange, ReportResult, TopologyMap,
|
||||
)
|
||||
from extras.constants import *
|
||||
from tenancy.api.serializers import NestedTenantSerializer, NestedTenantGroupSerializer
|
||||
@ -238,16 +238,3 @@ class ObjectChangeSerializer(serializers.ModelSerializer):
|
||||
context = {'request': self.context['request']}
|
||||
data = serializer(obj.changed_object, context=context).data
|
||||
return data
|
||||
|
||||
|
||||
#
|
||||
# User actions
|
||||
#
|
||||
|
||||
class UserActionSerializer(serializers.ModelSerializer):
|
||||
user = NestedUserSerializer()
|
||||
action = ChoiceField(choices=ACTION_CHOICES)
|
||||
|
||||
class Meta:
|
||||
model = UserAction
|
||||
fields = ['id', 'time', 'user', 'action', 'message']
|
||||
|
@ -41,8 +41,5 @@ router.register(r'reports', views.ReportViewSet, base_name='report')
|
||||
# Change logging
|
||||
router.register(r'object-changes', views.ObjectChangeViewSet)
|
||||
|
||||
# Recent activity
|
||||
router.register(r'recent-activity', views.RecentActivityViewSet)
|
||||
|
||||
app_name = 'extras-api'
|
||||
urlpatterns = router.urls
|
||||
|
@ -11,7 +11,6 @@ from taggit.models import Tag
|
||||
from extras import filters
|
||||
from extras.models import (
|
||||
ConfigContext, CustomField, ExportTemplate, Graph, ImageAttachment, ObjectChange, ReportResult, TopologyMap,
|
||||
UserAction,
|
||||
)
|
||||
from extras.reports import get_report, get_reports
|
||||
from utilities.api import FieldChoicesViewSet, IsAuthenticatedOrLoginNotRequired, ModelViewSet
|
||||
@ -230,16 +229,3 @@ class ObjectChangeViewSet(ReadOnlyModelViewSet):
|
||||
queryset = ObjectChange.objects.select_related('user')
|
||||
serializer_class = serializers.ObjectChangeSerializer
|
||||
filter_class = filters.ObjectChangeFilter
|
||||
|
||||
|
||||
#
|
||||
# User activity
|
||||
#
|
||||
|
||||
class RecentActivityViewSet(ReadOnlyModelViewSet):
|
||||
"""
|
||||
DEPRECATED: List all UserActions to provide a log of recent activity.
|
||||
"""
|
||||
queryset = UserAction.objects.all()
|
||||
serializer_class = serializers.UserActionSerializer
|
||||
filter_class = filters.UserActionFilter
|
||||
|
@ -1,5 +1,4 @@
|
||||
import django_filters
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db.models import Q
|
||||
from taggit.models import Tag
|
||||
@ -7,7 +6,7 @@ from taggit.models import Tag
|
||||
from dcim.models import DeviceRole, Platform, Region, Site
|
||||
from tenancy.models import Tenant, TenantGroup
|
||||
from .constants import CF_FILTER_DISABLED, CF_FILTER_EXACT, CF_TYPE_BOOLEAN, CF_TYPE_SELECT
|
||||
from .models import ConfigContext, CustomField, Graph, ExportTemplate, ObjectChange, TopologyMap, UserAction
|
||||
from .models import ConfigContext, CustomField, Graph, ExportTemplate, ObjectChange, TopologyMap
|
||||
|
||||
|
||||
class CustomFieldFilter(django_filters.Filter):
|
||||
@ -227,15 +226,3 @@ class ObjectChangeFilter(django_filters.FilterSet):
|
||||
Q(user_name__icontains=value) |
|
||||
Q(object_repr__icontains=value)
|
||||
)
|
||||
|
||||
|
||||
class UserActionFilter(django_filters.FilterSet):
|
||||
username = django_filters.ModelMultipleChoiceFilter(
|
||||
name='user__username',
|
||||
queryset=User.objects.all(),
|
||||
to_field_name='username',
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = UserAction
|
||||
fields = ['user']
|
||||
|
24
netbox/extras/migrations/0015_remove_useraction.py
Normal file
24
netbox/extras/migrations/0015_remove_useraction.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Generated by Django 2.0.8 on 2018-08-14 16:10
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('extras', '0014_configcontexts'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='useraction',
|
||||
name='content_type',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='useraction',
|
||||
name='user',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='UserAction',
|
||||
),
|
||||
]
|
@ -12,7 +12,6 @@ from django.db.models import Q
|
||||
from django.http import HttpResponse
|
||||
from django.template import Template, Context
|
||||
from django.urls import reverse
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from dcim.constants import CONNECTION_STATUS_CONNECTED
|
||||
from utilities.utils import foreground_color
|
||||
@ -842,100 +841,3 @@ class ObjectChange(models.Model):
|
||||
self.object_repr,
|
||||
self.object_data,
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# User actions
|
||||
#
|
||||
|
||||
class UserActionManager(models.Manager):
|
||||
|
||||
# Actions affecting a single object
|
||||
def log_action(self, user, obj, action, message):
|
||||
self.model.objects.create(
|
||||
content_type=ContentType.objects.get_for_model(obj),
|
||||
object_id=obj.pk,
|
||||
user=user,
|
||||
action=action,
|
||||
message=message,
|
||||
)
|
||||
|
||||
def log_create(self, user, obj, message=''):
|
||||
self.log_action(user, obj, ACTION_CREATE, message)
|
||||
|
||||
def log_edit(self, user, obj, message=''):
|
||||
self.log_action(user, obj, ACTION_EDIT, message)
|
||||
|
||||
def log_delete(self, user, obj, message=''):
|
||||
self.log_action(user, obj, ACTION_DELETE, message)
|
||||
|
||||
# Actions affecting multiple objects
|
||||
def log_bulk_action(self, user, content_type, action, message):
|
||||
self.model.objects.create(
|
||||
content_type=content_type,
|
||||
user=user,
|
||||
action=action,
|
||||
message=message,
|
||||
)
|
||||
|
||||
def log_import(self, user, content_type, message=''):
|
||||
self.log_bulk_action(user, content_type, ACTION_IMPORT, message)
|
||||
|
||||
def log_bulk_create(self, user, content_type, message=''):
|
||||
self.log_bulk_action(user, content_type, ACTION_BULK_CREATE, message)
|
||||
|
||||
def log_bulk_edit(self, user, content_type, message=''):
|
||||
self.log_bulk_action(user, content_type, ACTION_BULK_EDIT, message)
|
||||
|
||||
def log_bulk_delete(self, user, content_type, message=''):
|
||||
self.log_bulk_action(user, content_type, ACTION_BULK_DELETE, message)
|
||||
|
||||
|
||||
# TODO: Remove UserAction, which has been replaced by ObjectChange.
|
||||
class UserAction(models.Model):
|
||||
"""
|
||||
DEPRECATED: A record of an action (add, edit, or delete) performed on an object by a User.
|
||||
"""
|
||||
time = models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
editable=False
|
||||
)
|
||||
user = models.ForeignKey(
|
||||
to=User,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='actions'
|
||||
)
|
||||
content_type = models.ForeignKey(
|
||||
to=ContentType,
|
||||
on_delete=models.CASCADE
|
||||
)
|
||||
object_id = models.PositiveIntegerField(
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
action = models.PositiveSmallIntegerField(
|
||||
choices=ACTION_CHOICES
|
||||
)
|
||||
message = models.TextField(
|
||||
blank=True
|
||||
)
|
||||
|
||||
objects = UserActionManager()
|
||||
|
||||
class Meta:
|
||||
ordering = ['-time']
|
||||
|
||||
def __str__(self):
|
||||
if self.message:
|
||||
return '{} {}'.format(self.user, self.message)
|
||||
return '{} {} {}'.format(self.user, self.get_action_display(), self.content_type)
|
||||
|
||||
def icon(self):
|
||||
if self.action in [ACTION_CREATE, ACTION_BULK_CREATE, ACTION_IMPORT]:
|
||||
return mark_safe('<i class="glyphicon glyphicon-plus text-success"></i>')
|
||||
elif self.action in [ACTION_EDIT, ACTION_BULK_EDIT]:
|
||||
return mark_safe('<i class="glyphicon glyphicon-pencil text-warning"></i>')
|
||||
elif self.action in [ACTION_DELETE, ACTION_BULK_DELETE]:
|
||||
return mark_safe('<i class="glyphicon glyphicon-remove text-danger"></i>')
|
||||
else:
|
||||
return ''
|
||||
|
@ -21,9 +21,6 @@
|
||||
<li{% ifequal active_tab "userkey" %} class="active"{% endifequal %}>
|
||||
<a href="{% url 'user:userkey' %}">User Key</a>
|
||||
</li>
|
||||
<li{% ifequal active_tab "recent_activity" %} class="active"{% endifequal %}>
|
||||
<a href="{% url 'user:recent_activity' %}">Recent Activity</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-sm-9 col-md-6">
|
||||
|
@ -1,22 +0,0 @@
|
||||
{% extends 'users/_user.html' %}
|
||||
|
||||
{% block title %}Recent Activity{% endblock %}
|
||||
|
||||
{% block usercontent %}
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Time</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for action in recent_activity %}
|
||||
<tr>
|
||||
<td>{{ action.time|date:'SHORT_DATETIME_FORMAT' }}</td>
|
||||
<td>{{ action.icon }} {{ action.message|safe }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
@ -14,6 +14,5 @@ urlpatterns = [
|
||||
url(r'^user-key/$', views.UserKeyView.as_view(), name='userkey'),
|
||||
url(r'^user-key/edit/$', views.UserKeyEditView.as_view(), name='userkey_edit'),
|
||||
url(r'^session-key/delete/$', views.SessionKeyDeleteView.as_view(), name='sessionkey_delete'),
|
||||
url(r'^recent-activity/$', views.RecentActivityView.as_view(), name='recent_activity'),
|
||||
|
||||
]
|
||||
|
@ -196,18 +196,6 @@ class SessionKeyDeleteView(LoginRequiredMixin, View):
|
||||
})
|
||||
|
||||
|
||||
@method_decorator(login_required, name='dispatch')
|
||||
class RecentActivityView(View):
|
||||
template_name = 'users/recent_activity.html'
|
||||
|
||||
def get(self, request):
|
||||
|
||||
return render(request, self.template_name, {
|
||||
'recent_activity': request.user.actions.all()[:50],
|
||||
'active_tab': 'recent_activity',
|
||||
})
|
||||
|
||||
|
||||
#
|
||||
# API tokens
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user