DIR path: Directory Tree.jpg
tests/admin.py:
from django.forms import ModelForm
from openwisp_utils.admin import AlwaysHasChangedMixin, ReadOnlyAdmin
from .models import Operator, Project, RadiusAccounting
@admin.register(Operator)
class OperatorAdmin(admin.ModelAdmin):
list_display = ['first_name', 'last_name']
@admin.register(RadiusAccounting)
class RadiusAccountingAdmin(ReadOnlyAdmin):
list_display = ['session_id', 'username']
fields = ['session_id', 'username']
class OperatorForm(AlwaysHasChangedMixin, ModelForm):
pass
class OperatorInline(admin.StackedInline):
model = Operator
form = OperatorForm
extra = 0
@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
inlines = [OperatorInline]
list_display = ['name']
openwisp_utils/admin.py:
from django.contrib.admin import ModelAdmin
class TimeReadonlyAdminMixin(object):
"""
mixin that automatically flags
`created` and `modified` as readonly
"""
def __init__(self, *args, **kwargs):
self.readonly_fields += ('created', 'modified',)
super(TimeReadonlyAdminMixin, self).__init__(*args, **kwargs)
class ReadOnlyAdmin(ModelAdmin):
"""
Disables all editing capabilities
"""
def __init__(self, *args, **kwargs):
super(ReadOnlyAdmin, self).__init__(*args, **kwargs)
self.readonly_fields = [f.name for f in self.model._meta.fields]
def get_actions(self, request):
actions = super(ReadOnlyAdmin, self).get_actions(request)
if 'delete_selected' in actions: # pragma: no cover
del actions['delete_selected']
return actions
def has_add_permission(self, request):
return False
def has_delete_permission(self, request, obj=None):
return False
def save_model(self, request, obj, form, change): # pragma: nocover
pass
def delete_model(self, request, obj): # pragma: nocover
pass
def save_related(self, request, form, formsets, change): # pragma: nocover
pass
def change_view(self, request, object_id, extra_context=None):
extra_context = extra_context or {}
extra_context['show_save_and_continue'] = False
extra_context['show_save'] = False
return super(ReadOnlyAdmin, self).change_view(request,
object_id,
extra_context=extra_context)
class AlwaysHasChangedMixin(object):
def has_changed(self):
"""
This django-admin trick ensures the settings
are saved even if default values are unchanged
(without this trick new setting objects won't be
created unless users change the default values)
"""
if self.instance._state.adding:
return True
return super(AlwaysHasChangedMixin, self).has_changed()
Error: Error Snippet.jpg
This import error is coming up upon migrating the above code....please help on how to fix this import error.
Both openwisp_utils and tests files are under same parent folder.
Is there anything to change/add in the settings.py file of "tests" project before importing from "openwisp_utils"?