diff --git a/src/registrar/admin.py b/src/registrar/admin.py
index ac9f01925..f3287be27 100644
--- a/src/registrar/admin.py
+++ b/src/registrar/admin.py
@@ -1511,7 +1511,7 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin):
]
# Readonly fields for analysts and superusers
- readonly_fields = ("other_contacts", "is_election_board", "domain_managers", "invited_domain_managers")
+ readonly_fields = ("other_contacts", "is_election_board")
# Read only that we'll leverage for CISA Analysts
analyst_readonly_fields = [
@@ -1606,70 +1606,6 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin):
return super().formfield_for_foreignkey(db_field, request, use_admin_sort_fields=use_sort, **kwargs)
- def get_domain_managers(self, obj):
- user_domain_roles = UserDomainRole.objects.filter(domain=obj.domain)
- user_ids = user_domain_roles.values_list("user_id", flat=True)
- domain_managers = User.objects.filter(id__in=user_ids)
- return domain_managers
-
- def get_domain_invitations(self, obj):
- domain_invitations = DomainInvitation.objects.filter(
- domain=obj.domain, status=DomainInvitation.DomainInvitationStatus.INVITED
- )
- return domain_invitations
-
- @admin.display(description='Domain managers')
- def domain_managers(self, obj):
- """Get joined users who have roles/perms that are not Admin, unpack and return an HTML block.
-
- DJA readonly can't handle querysets, so we need to unpack and return html here.
- Alternatively, we could return querysets in context but that would limit where this
- data would display in a custom change form without extensive template customization.
-
- Will be used in the after_help_text block."""
- domain_managers = self.get_domain_managers(obj)
- if not domain_managers:
- return "No domain managers found."
-
- domain_manager_details = "
UID | Name | Email | " + "
"
- for domain_manager in domain_managers:
- full_name = domain_manager.get_formatted_name()
- change_url = reverse("admin:registrar_user_change", args=[domain_manager.pk])
- domain_manager_details += ""
- domain_manager_details += f'{escape(domain_manager.username)}'
- domain_manager_details += f" | {escape(full_name)} | "
- domain_manager_details += f"{escape(domain_manager.email)} | "
- domain_manager_details += "
"
- domain_manager_details += "
"
- return format_html(domain_manager_details)
-
- domain_managers.short_description = "Domain managers" # type: ignore
-
- @admin.display(description='Invited domain managers')
- def invited_domain_managers(self, obj):
- """Get emails which have been invited to the domain, unpack and return an HTML block.
-
- DJA readonly can't handle querysets, so we need to unpack and return html here.
- Alternatively, we could return querysets in context but that would limit where this
- data would display in a custom change form without extensive template customization.
-
- Will be used in the after_help_text block."""
- domain_invitations = self.get_domain_invitations(obj)
- if not domain_invitations:
- return "No invited domain managers found."
-
- domain_invitation_details = "Email | Status | " + "
"
- for domain_invitation in domain_invitations:
- domain_invitation_details += ""
- domain_invitation_details += f"{escape(domain_invitation.email)} | "
- domain_invitation_details += f"{escape(domain_invitation.status.capitalize())} | "
- domain_invitation_details += "
"
- domain_invitation_details += "
"
- return format_html(domain_invitation_details)
-
- invited_domain_managers.short_description = "Invited domain managers" # type: ignore
-
-
class DomainRequestResource(FsmModelResource):
"""defines how each field in the referenced model should be mapped to the corresponding fields in the
import/export file"""
@@ -2405,23 +2341,10 @@ class DomainInformationInline(admin.StackedInline):
template = "django/admin/includes/domain_info_inline_stacked.html"
model = models.DomainInformation
- fieldsets = list(DomainInformationAdmin.fieldsets)
- readonly_fields = list(DomainInformationAdmin.readonly_fields)
- analyst_readonly_fields = DomainInformationAdmin.analyst_readonly_fields
- autocomplete_fields = DomainInformationAdmin.autocomplete_fields
+ fieldsets = copy.deepcopy(list(DomainInformationAdmin.fieldsets))
+ analyst_readonly_fields = copy.deepcopy(DomainInformationAdmin.analyst_readonly_fields)
+ autocomplete_fields = copy.deepcopy(DomainInformationAdmin.autocomplete_fields)
- readonly_fields.extend(["domain_managers", "invited_domain_managers"]) # type: ignore
- # Removing specific fields from the first fieldset dynamically
- fieldsets[0][1]["fields"] = [
- field for field in fieldsets[0][1]["fields"] if field not in ["creator", "submitter", "domain_request", "notes"]
- ]
- fieldsets[2][1]["fields"] = [
- field for field in fieldsets[2][1]["fields"] if field not in ["other_contacts", "no_other_contacts_rationale"]
- ]
- fieldsets[2][1]["fields"].extend(["domain_managers", "invited_domain_managers"]) # type: ignore
- fieldsets_to_move = fieldsets.pop(3)
- fieldsets.append(fieldsets_to_move)
-
def get_domain_managers(self, obj):
user_domain_roles = UserDomainRole.objects.filter(domain=obj.domain)
user_ids = user_domain_roles.values_list("user_id", flat=True)
@@ -2434,7 +2357,6 @@ class DomainInformationInline(admin.StackedInline):
)
return domain_invitations
- @admin.display(description='Domain managers')
def domain_managers(self, obj):
"""Get joined users who have roles/perms that are not Admin, unpack and return an HTML block.
@@ -2461,7 +2383,6 @@ class DomainInformationInline(admin.StackedInline):
domain_managers.short_description = "Domain managers" # type: ignore
- @admin.display(description='Invited domain managers')
def invited_domain_managers(self, obj):
"""Get emails which have been invited to the domain, unpack and return an HTML block.
@@ -2523,7 +2444,9 @@ class DomainInformationInline(admin.StackedInline):
return super().formfield_for_foreignkey(db_field, request, **kwargs)
def get_readonly_fields(self, request, obj=None):
- return DomainInformationAdmin.get_readonly_fields(self, request, obj=None)
+ readonly_fields = copy.deepcopy(DomainInformationAdmin.get_readonly_fields(self, request, obj=None))
+ readonly_fields.extend(["domain_managers", "invited_domain_managers"]) # type: ignore
+ return readonly_fields
# Re-route the get_fieldsets method to utilize DomainInformationAdmin.get_fieldsets
# since that has all the logic for excluding certain fields according to user permissions.
@@ -2532,14 +2455,30 @@ class DomainInformationInline(admin.StackedInline):
def get_fieldsets(self, request, obj=None):
# Grab fieldsets from DomainInformationAdmin so that it handles all logic
# for permission-based field visibility.
- modified_fieldsets = DomainInformationAdmin.get_fieldsets(self, request, obj=None)
+ modified_fieldsets = copy.deepcopy(DomainInformationAdmin.get_fieldsets(self, request, obj=None))
- # remove .gov domain from fieldset
+ # Modify fieldset sections in place
+ for index, (title, f) in enumerate(modified_fieldsets):
+ if title is None:
+ modified_fieldsets[index][1]["fields"] = [
+ field for field in modified_fieldsets[index][1]["fields"] if field not in ["creator", "domain_request", "notes"]
+ ]
+ elif title == "Contacts":
+ modified_fieldsets[index][1]["fields"] = [
+ field for field in modified_fieldsets[index][1]["fields"] if field not in ["other_contacts", "no_other_contacts_rationale"]
+ ]
+ modified_fieldsets[index][1]["fields"].extend(["domain_managers", "invited_domain_managers"]) # type: ignore
+
+ # Remove or remove fieldset sections
for index, (title, f) in enumerate(modified_fieldsets):
if title == ".gov domain":
- del modified_fieldsets[index]
- break
-
+ # remove .gov domain from fieldset
+ modified_fieldsets.pop(index)
+ elif title == "Background info":
+ # move Background info to the bottom of the list
+ fieldsets_to_move = modified_fieldsets.pop(index)
+ modified_fieldsets.append(fieldsets_to_move)
+
return modified_fieldsets
diff --git a/src/registrar/tests/test_admin_domain.py b/src/registrar/tests/test_admin_domain.py
index bfbdad81d..a9b94781f 100644
--- a/src/registrar/tests/test_admin_domain.py
+++ b/src/registrar/tests/test_admin_domain.py
@@ -167,12 +167,6 @@ class TestDomainAdminAsStaff(MockEppLib):
expected_organization_name = "MonkeySeeMonkeyDo"
self.assertContains(response, expected_organization_name)
- # clean up this test's data
- domain.delete()
- domain_information.delete()
- _domain_request.delete()
- _creator.delete()
-
@less_console_noise_decorator
def test_deletion_is_successful(self):
"""
@@ -227,9 +221,6 @@ class TestDomainAdminAsStaff(MockEppLib):
self.assertEqual(domain.state, Domain.State.DELETED)
- # clean up data within this test
- domain.delete()
-
@less_console_noise_decorator
def test_deletion_ready_fsm_failure(self):
"""
@@ -269,9 +260,6 @@ class TestDomainAdminAsStaff(MockEppLib):
self.assertEqual(domain.state, Domain.State.READY)
- # delete data created in this test
- domain.delete()
-
@less_console_noise_decorator
def test_analyst_deletes_domain_idempotent(self):
"""
@@ -330,9 +318,6 @@ class TestDomainAdminAsStaff(MockEppLib):
)
self.assertEqual(domain.state, Domain.State.DELETED)
- # delete data created in this test
- domain.delete()
-
class TestDomainInformationInline(MockEppLib):
"""Test DomainAdmin class, specifically the DomainInformationInline class, as staff user.
@@ -540,17 +525,6 @@ class TestDomainAdminWithClient(TestCase):
self.assertContains(response, domain.name)
# Check that the fields have the right values.
- # == Check for the creator == #
-
- # Check for the right title, email, and phone number in the response.
- # We only need to check for the end tag
- # (Otherwise this test will fail if we change classes, etc)
- self.assertContains(response, "Treat inspector")
- self.assertContains(response, "meoward.jones@igorville.gov")
- self.assertContains(response, "(555) 123 12345")
-
- # Check for the field itself
- self.assertContains(response, "Meoward Jones")
# == Check for the senior_official == #
self.assertContains(response, "testy@town.com")
@@ -560,11 +534,6 @@ class TestDomainAdminWithClient(TestCase):
# Includes things like readonly fields
self.assertContains(response, "Testy Tester")
- # == Test the other_employees field == #
- self.assertContains(response, "testy2@town.com")
- self.assertContains(response, "Another Tester")
- self.assertContains(response, "(555) 555 5557")
-
# Test for the copy link
self.assertContains(response, "button--clipboard")