Cleanup and unit test fixes

This commit is contained in:
CocoByte 2024-12-04 19:43:39 -07:00
parent 3b9e9e39eb
commit 87a9655828
No known key found for this signature in database
GPG key ID: BBFAA2526384C97F
5 changed files with 87 additions and 73 deletions

View file

@ -1760,10 +1760,6 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
Q(portfolio__federal_agency__federal_type=self.value()) | Q(portfolio__federal_agency__federal_type=self.value()) |
Q(portfolio__isnull=True, federal_type=self.value()) Q(portfolio__isnull=True, federal_type=self.value())
) )
# return queryset.filter(
# Q(portfolio__federal_type=self.value()) |
# Q(portfolio__isnull=True, federal_type=self.value())
# )
return queryset return queryset
class InvestigatorFilter(admin.SimpleListFilter): class InvestigatorFilter(admin.SimpleListFilter):
@ -2778,8 +2774,6 @@ class DomainAdmin(ListHeaderAdmin, ImportExportModelAdmin):
# Filter queryset # Filter queryset
def queryset(self, request, queryset): def queryset(self, request, queryset):
if self.value(): # Check if a generic org is selected in the filter if self.value(): # Check if a generic org is selected in the filter
# return queryset.filter(converted_generic_org_type = self.value)
return queryset.filter( return queryset.filter(
Q(domain_info__portfolio__organization_type=self.value()) | Q(domain_info__portfolio__organization_type=self.value()) |
Q(domain_info__portfolio__isnull=True, domain_info__generic_org_type=self.value()) Q(domain_info__portfolio__isnull=True, domain_info__generic_org_type=self.value())

View file

@ -563,9 +563,10 @@ class MockDb(TestCase):
cls.federal_agency_1, _ = FederalAgency.objects.get_or_create(agency="World War I Centennial Commission") cls.federal_agency_1, _ = FederalAgency.objects.get_or_create(agency="World War I Centennial Commission")
cls.federal_agency_2, _ = FederalAgency.objects.get_or_create(agency="Armed Forces Retirement Home") cls.federal_agency_2, _ = FederalAgency.objects.get_or_create(agency="Armed Forces Retirement Home")
cls.federal_agency_3, _ = FederalAgency.objects.get_or_create(agency="Portfolio 1 Federal Agency",federal_type="executive")
cls.portfolio_1, _ = Portfolio.objects.get_or_create( cls.portfolio_1, _ = Portfolio.objects.get_or_create(
creator=cls.custom_superuser, federal_agency=cls.federal_agency_1 creator=cls.custom_superuser, federal_agency=cls.federal_agency_3, organization_type="federal"
) )
current_date = get_time_aware_date(datetime(2024, 4, 2)) current_date = get_time_aware_date(datetime(2024, 4, 2))

View file

@ -30,6 +30,9 @@ from .common import (
from unittest.mock import ANY, call, patch from unittest.mock import ANY, call, patch
import boto3_mocking # type: ignore import boto3_mocking # type: ignore
import logging
logger = logging.getLogger(__name__)
class TestDomainAdminAsStaff(MockEppLib): class TestDomainAdminAsStaff(MockEppLib):
@ -723,9 +726,9 @@ class TestDomainAdminWithClient(TestCase):
domain_request.approve() domain_request.approve()
response = self.client.get("/admin/registrar/domain/") response = self.client.get("/admin/registrar/domain/")
# The total count should reflect the fact that we are pulling from portfolio # There are 4 template references to Federal (4) plus four references in the table
# data when portfolios are present # for our actual domain_request
self.assertContains(response, "Federal", count=98) self.assertContains(response, "Federal", count=57)
# This may be a bit more robust # This may be a bit more robust
self.assertContains(response, '<td class="field-generic_org_type">Federal</td>', count=1) self.assertContains(response, '<td class="field-generic_org_type">Federal</td>', count=1)
# Now let's make sure the long description does not exist # Now let's make sure the long description does not exist

View file

@ -53,6 +53,12 @@ from datetime import datetime
from django.contrib.admin.models import LogEntry, ADDITION from django.contrib.admin.models import LogEntry, ADDITION
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
# ---Logger
import logging
from venv import logger
from registrar.management.commands.utility.terminal_helper import TerminalColors, TerminalHelper
logger = logging.getLogger(__name__)
class CsvReportsTest(MockDbForSharedTests): class CsvReportsTest(MockDbForSharedTests):
"""Tests to determine if we are uploading our reports correctly.""" """Tests to determine if we are uploading our reports correctly."""
@ -71,8 +77,8 @@ class CsvReportsTest(MockDbForSharedTests):
fake_open = mock_open() fake_open = mock_open()
expected_file_content = [ expected_file_content = [
call("Domain name,Domain type,Agency,Organization name,City,State,Security contact email\r\n"), call("Domain name,Domain type,Agency,Organization name,City,State,Security contact email\r\n"),
call("cdomain1.gov,Federal - Executive,Portfolio 1 Federal Agency,,,,(blank)\r\n"),
call("cdomain11.gov,Federal - Executive,World War I Centennial Commission,,,,(blank)\r\n"), call("cdomain11.gov,Federal - Executive,World War I Centennial Commission,,,,(blank)\r\n"),
call("cdomain1.gov,Federal - Executive,World War I Centennial Commission,,,,(blank)\r\n"),
call("adomain10.gov,Federal,Armed Forces Retirement Home,,,,(blank)\r\n"), call("adomain10.gov,Federal,Armed Forces Retirement Home,,,,(blank)\r\n"),
call("ddomain3.gov,Federal,Armed Forces Retirement Home,,,,(blank)\r\n"), call("ddomain3.gov,Federal,Armed Forces Retirement Home,,,,(blank)\r\n"),
] ]
@ -93,8 +99,8 @@ class CsvReportsTest(MockDbForSharedTests):
fake_open = mock_open() fake_open = mock_open()
expected_file_content = [ expected_file_content = [
call("Domain name,Domain type,Agency,Organization name,City,State,Security contact email\r\n"), call("Domain name,Domain type,Agency,Organization name,City,State,Security contact email\r\n"),
call("cdomain1.gov,Federal - Executive,Portfolio 1 Federal Agency,,,,(blank)\r\n"),
call("cdomain11.gov,Federal - Executive,World War I Centennial Commission,,,,(blank)\r\n"), call("cdomain11.gov,Federal - Executive,World War I Centennial Commission,,,,(blank)\r\n"),
call("cdomain1.gov,Federal - Executive,World War I Centennial Commission,,,,(blank)\r\n"),
call("adomain10.gov,Federal,Armed Forces Retirement Home,,,,(blank)\r\n"), call("adomain10.gov,Federal,Armed Forces Retirement Home,,,,(blank)\r\n"),
call("ddomain3.gov,Federal,Armed Forces Retirement Home,,,,(blank)\r\n"), call("ddomain3.gov,Federal,Armed Forces Retirement Home,,,,(blank)\r\n"),
call("zdomain12.gov,Interstate,,,,,(blank)\r\n"), call("zdomain12.gov,Interstate,,,,,(blank)\r\n"),
@ -251,25 +257,23 @@ class ExportDataTest(MockDbForIndividualTests, MockEppLib):
# We expect READY domains, # We expect READY domains,
# sorted alphabetially by domain name # sorted alphabetially by domain name
expected_content = ( expected_content = (
"Domain name,Status,First ready on,Expiration date,Domain type,Agency,Organization name,City,State,SO," "Domain name,Status,First ready on,Expiration date,Domain type,Agency,Organization name,City,State,SO,SO email,"
"SO email,Security contact email,Domain managers,Invited domain managers\n" "Security contact email,Domain managers,Invited domain managers\n"
"cdomain11.gov,Ready,2024-04-02,(blank),Federal - Executive,WorldWarICentennialCommission" "adomain2.gov,Dns needed,(blank),(blank),Federal - Executive,Portfolio 1 Federal Agency,,,, ,,(blank),"
",,,, ,,(blank),meoward@rocks.com,\n" "meoward@rocks.com,squeaker@rocks.com\n"
"defaultsecurity.gov,Ready,2023-11-01,(blank),Federal - Executive,WorldWarICentennialCommission" "defaultsecurity.gov,Ready,2023-11-01,(blank),Federal - Executive,Portfolio 1 Federal Agency,,,, ,,(blank),"
",,,, ,,(blank),"
'"big_lebowski@dude.co, info@example.com, meoward@rocks.com",woofwardthethird@rocks.com\n' '"big_lebowski@dude.co, info@example.com, meoward@rocks.com",woofwardthethird@rocks.com\n'
"adomain10.gov,Ready,2024-04-03,(blank),Federal,ArmedForcesRetirementHome,,,, ,,(blank),," "cdomain11.gov,Ready,2024-04-02,(blank),Federal - Executive,World War I Centennial Commission,,,, ,,(blank),"
"squeaker@rocks.com\n" "meoward@rocks.com,\n"
"bdomain4.gov,Unknown,(blank),(blank),Federal,ArmedForcesRetirementHome,,,, ,,(blank),,\n" "adomain10.gov,Ready,2024-04-03,(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,"
"bdomain5.gov,Deleted,(blank),(blank),Federal,ArmedForcesRetirementHome,,,, ,,(blank),,\n"
"bdomain6.gov,Deleted,(blank),(blank),Federal,ArmedForcesRetirementHome,,,, ,,(blank),,\n"
"ddomain3.gov,On hold,(blank),2023-11-15,Federal,ArmedForcesRetirementHome,,,, ,,"
"security@mail.gov,,\n"
"sdomain8.gov,Deleted,(blank),(blank),Federal,ArmedForcesRetirementHome,,,, ,,(blank),,\n"
"xdomain7.gov,Deleted,(blank),(blank),Federal,ArmedForcesRetirementHome,,,, ,,(blank),,\n"
"zdomain9.gov,Deleted,(blank),(blank),Federal,ArmedForcesRetirementHome,,,, ,,(blank),,\n"
"adomain2.gov,Dns needed,(blank),(blank),Interstate,,,,, ,,(blank),meoward@rocks.com,"
"squeaker@rocks.com\n" "squeaker@rocks.com\n"
"bdomain4.gov,Unknown,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n"
"bdomain5.gov,Deleted,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n"
"bdomain6.gov,Deleted,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n"
"ddomain3.gov,On hold,(blank),2023-11-15,Federal,Armed Forces Retirement Home,,,, ,,security@mail.gov,,\n"
"sdomain8.gov,Deleted,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n"
"xdomain7.gov,Deleted,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n"
"zdomain9.gov,Deleted,(blank),(blank),Federal,Armed Forces Retirement Home,,,, ,,(blank),,\n"
"zdomain12.gov,Ready,2024-04-02,(blank),Interstate,,,,, ,,(blank),meoward@rocks.com,\n" "zdomain12.gov,Ready,2024-04-02,(blank),Interstate,,,,, ,,(blank),meoward@rocks.com,\n"
) )
@ -313,13 +317,11 @@ class ExportDataTest(MockDbForIndividualTests, MockEppLib):
# We expect only domains associated with the user # We expect only domains associated with the user
expected_content = ( expected_content = (
"Domain name,Status,First ready on,Expiration date,Domain type,Agency,Organization name," "Domain name,Status,First ready on,Expiration date,Domain type,Agency,Organization name,"
"City,State,SO,SO email," "City,State,SO,SO email,Security contact email,Domain managers,Invited domain managers\n"
"Security contact email,Domain managers,Invited domain managers\n" "adomain2.gov,Dns needed,(blank),(blank),Federal - Executive,Portfolio 1 Federal Agency,,,, ,,(blank),"
"defaultsecurity.gov,Ready,2023-11-01,(blank),Federal - Executive,"
"WorldWarICentennialCommission,,,, ,,(blank),"
'"big_lebowski@dude.co, info@example.com, meoward@rocks.com",woofwardthethird@rocks.com\n'
"adomain2.gov,Dns needed,(blank),(blank),Interstate,,,,, ,,(blank),"
'"info@example.com, meoward@rocks.com",squeaker@rocks.com\n' '"info@example.com, meoward@rocks.com",squeaker@rocks.com\n'
"defaultsecurity.gov,Ready,2023-11-01,(blank),Federal - Executive,Portfolio 1 Federal Agency,,,, ,,(blank),"
'"big_lebowski@dude.co, info@example.com, meoward@rocks.com",woofwardthethird@rocks.com\n'
) )
# Normalize line endings and remove commas, # Normalize line endings and remove commas,
@ -494,8 +496,8 @@ class ExportDataTest(MockDbForIndividualTests, MockEppLib):
# sorted alphabetially by domain name # sorted alphabetially by domain name
expected_content = ( expected_content = (
"Domain name,Domain type,Agency,Organization name,City,State,Security contact email\n" "Domain name,Domain type,Agency,Organization name,City,State,Security contact email\n"
"defaultsecurity.gov,Federal - Executive,Portfolio1FederalAgency,,,,(blank)\n"
"cdomain11.gov,Federal - Executive,WorldWarICentennialCommission,,,,(blank)\n" "cdomain11.gov,Federal - Executive,WorldWarICentennialCommission,,,,(blank)\n"
"defaultsecurity.gov,Federal - Executive,WorldWarICentennialCommission,,,,(blank)\n"
"adomain10.gov,Federal,ArmedForcesRetirementHome,,,,(blank)\n" "adomain10.gov,Federal,ArmedForcesRetirementHome,,,,(blank)\n"
"ddomain3.gov,Federal,ArmedForcesRetirementHome,,,,security@mail.gov\n" "ddomain3.gov,Federal,ArmedForcesRetirementHome,,,,security@mail.gov\n"
"zdomain12.gov,Interstate,,,,,(blank)\n" "zdomain12.gov,Interstate,,,,,(blank)\n"
@ -535,8 +537,8 @@ class ExportDataTest(MockDbForIndividualTests, MockEppLib):
# sorted alphabetially by domain name # sorted alphabetially by domain name
expected_content = ( expected_content = (
"Domain name,Domain type,Agency,Organization name,City,State,Security contact email\n" "Domain name,Domain type,Agency,Organization name,City,State,Security contact email\n"
"defaultsecurity.gov,Federal - Executive,Portfolio1FederalAgency,,,,(blank)\n"
"cdomain11.gov,Federal - Executive,WorldWarICentennialCommission,,,,(blank)\n" "cdomain11.gov,Federal - Executive,WorldWarICentennialCommission,,,,(blank)\n"
"defaultsecurity.gov,Federal - Executive,WorldWarICentennialCommission,,,,(blank)\n"
"adomain10.gov,Federal,ArmedForcesRetirementHome,,,,(blank)\n" "adomain10.gov,Federal,ArmedForcesRetirementHome,,,,(blank)\n"
"ddomain3.gov,Federal,ArmedForcesRetirementHome,,,,security@mail.gov\n" "ddomain3.gov,Federal,ArmedForcesRetirementHome,,,,security@mail.gov\n"
) )
@ -591,7 +593,7 @@ class ExportDataTest(MockDbForIndividualTests, MockEppLib):
expected_content = ( expected_content = (
"Domain name,Domain type,Agency,Organization name,City," "Domain name,Domain type,Agency,Organization name,City,"
"State,Status,Expiration date, Deleted\n" "State,Status,Expiration date, Deleted\n"
"cdomain1.gov,Federal-Executive,WorldWarICentennialCommission,Ready,(blank)\n" "cdomain1.gov,Federal-Executive,Portfolio1FederalAgency,Ready,(blank)\n"
"adomain10.gov,Federal,ArmedForcesRetirementHome,Ready,(blank)\n" "adomain10.gov,Federal,ArmedForcesRetirementHome,Ready,(blank)\n"
"cdomain11.gov,Federal-Executive,WorldWarICentennialCommission,Ready,(blank)\n" "cdomain11.gov,Federal-Executive,WorldWarICentennialCommission,Ready,(blank)\n"
"zdomain12.gov,Interstate,Ready,(blank)\n" "zdomain12.gov,Interstate,Ready,(blank)\n"
@ -726,8 +728,9 @@ class ExportDataTest(MockDbForIndividualTests, MockEppLib):
expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip() expected_content = expected_content.replace(",,", "").replace(",", "").replace(" ", "").strip()
self.assertEqual(csv_content, expected_content) self.assertEqual(csv_content, expected_content)
@less_console_noise_decorator # @less_console_noise_decorator
def test_domain_request_data_full(self): def test_domain_request_data_full(self):
self.maxDiff = None
"""Tests the full domain request report.""" """Tests the full domain request report."""
# Remove "Submitted at" because we can't guess this immutable, dynamically generated test data # Remove "Submitted at" because we can't guess this immutable, dynamically generated test data
columns = [ columns = [
@ -768,35 +771,31 @@ class ExportDataTest(MockDbForIndividualTests, MockEppLib):
csv_file.seek(0) csv_file.seek(0)
# Read the content into a variable # Read the content into a variable
csv_content = csv_file.read() csv_content = csv_file.read()
expected_content = ( expected_content = (
# Header # Header
"Domain request,Status,Domain type,Federal type," "Domain request,Status,Domain type,Federal type,Federal agency,Organization name,Election office,"
"Federal agency,Organization name,Election office,City,State/territory," "City,State/territory,Region,Creator first name,Creator last name,Creator email,"
"Region,Creator first name,Creator last name,Creator email,Creator approved domains count," "Creator approved domains count,Creator active requests count,Alternative domains,SO first name,"
"Creator active requests count,Alternative domains,SO first name,SO last name,SO email," "SO last name,SO email,SO title/role,Request purpose,Request additional details,Other contacts,"
"SO title/role,Request purpose,Request additional details,Other contacts,"
"CISA regional representative,Current websites,Investigator\n" "CISA regional representative,Current websites,Investigator\n"
# Content # Content
"city5.gov,,Approved,Federal,Executive,,Testorg,N/A,,NY,2,,,,1,0,city1.gov,Testy,Tester,testy@town.com," "city5.gov,Approved,Federal,Executive,,Testorg,N/A,,NY,2,,,,1,0,city1.gov,Testy,Tester,testy@town.com,"
"Chief Tester,Purpose of the site,There is more,Testy Tester testy2@town.com,,city.com,\n" "Chief Tester,Purpose of the site,There is more,Testy Tester testy2@town.com,,city.com,\n"
"city2.gov,,In review,Federal,Executive,,Testorg,N/A,,NY,2,,,,0,1,city1.gov,Testy,Tester," "city2.gov,In review,Federal,Executive,Portfolio 1 Federal Agency,,N/A,,,2,,,,0,1,city1.gov,,,,,"
"testy@town.com," "Purpose of the site,There is more,Testy Tester testy2@town.com,,city.com,\n"
"Chief Tester,Purpose of the site,There is more,Testy Tester testy2@town.com,,city.com,\n" "city3.gov,Submitted,Federal,Executive,Portfolio 1 Federal Agency,,N/A,,,2,,,,0,1,"
'city3.gov,Submitted,Federal,Executive,,Testorg,N/A,,NY,2,,,,0,1,"cheeseville.gov, city1.gov,' '"cheeseville.gov, city1.gov, igorville.gov",,,,,Purpose of the site,CISA-first-name CISA-last-name | '
'igorville.gov",Testy,Tester,testy@town.com,Chief Tester,Purpose of the site,CISA-first-name ' 'There is more,"Meow Tester24 te2@town.com, Testy1232 Tester24 te2@town.com, Testy Tester testy2@town.com",'
"CISA-last-name " "test@igorville.com,\"city.com, https://www.example2.com, https://www.example.com\",\n"
'| There is more,"Meow Tester24 te2@town.com, Testy1232 Tester24 te2@town.com, Testy Tester '
'testy2@town.com"'
',test@igorville.com,"city.com, https://www.example2.com, https://www.example.com",\n'
"city4.gov,Submitted,City,Executive,,Testorg,Yes,,NY,2,,,,0,1,city1.gov,Testy,Tester,testy@town.com," "city4.gov,Submitted,City,Executive,,Testorg,Yes,,NY,2,,,,0,1,city1.gov,Testy,Tester,testy@town.com,"
"Chief Tester,Purpose of the site,CISA-first-name CISA-last-name | There is more,Testy Tester " "Chief Tester,Purpose of the site,CISA-first-name CISA-last-name | There is more,Testy Tester testy2@town.com,"
"testy2@town.com" "cisaRep@igorville.gov,city.com,\n"
",cisaRep@igorville.gov,city.com,\n" "city6.gov,Submitted,Federal,Executive,Portfolio 1 Federal Agency,,N/A,,,2,,,,0,1,city1.gov,,,,,"
"city6.gov,Submitted,Federal,Executive,,Testorg,N/A,,NY,2,,,,0,1,city1.gov,Testy,Tester,testy@town.com," "Purpose of the site,CISA-first-name CISA-last-name | There is more,Testy Tester testy2@town.com,"
"Chief Tester,Purpose of the site,CISA-first-name CISA-last-name | There is more,Testy Tester "
"testy2@town.com,"
"cisaRep@igorville.gov,city.com,\n" "cisaRep@igorville.gov,city.com,\n"
) )
# Normalize line endings and remove commas, # Normalize line endings and remove commas,
# spaces and leading/trailing whitespace # spaces and leading/trailing whitespace
csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip() csv_content = csv_content.replace(",,", "").replace(",", "").replace(" ", "").replace("\r\n", "\n").strip()

View file

@ -138,7 +138,7 @@ class BaseExport(ABC):
return Q() return Q()
@classmethod @classmethod
def get_computed_fields(cls, delimiter=", ", **kwargs): def get_computed_fields(cls, **kwargs):
""" """
Get a dict of computed fields. These are fields that do not exist on the model normally Get a dict of computed fields. These are fields that do not exist on the model normally
and will be passed to .annotate() when building a queryset. and will be passed to .annotate() when building a queryset.
@ -526,7 +526,7 @@ class DomainExport(BaseExport):
return DomainInformation return DomainInformation
@classmethod @classmethod
def get_computed_fields(cls, delimiter=", ", **kwargs): def get_computed_fields(cls, **kwargs):
""" """
Get a dict of computed fields. Get a dict of computed fields.
""" """
@ -776,7 +776,7 @@ class DomainExport(BaseExport):
portfolio__isnull=False, portfolio__isnull=False,
then=F("portfolio__organization_type") then=F("portfolio__organization_type")
), ),
default=F("organization_type"), default=F("generic_org_type"),
output_field=CharField(), output_field=CharField(),
) )
) )
@ -880,7 +880,7 @@ class DomainDataType(DomainExport):
] ]
@classmethod @classmethod
def get_annotations_for_sort(cls, delimiter=", "): def get_annotations_for_sort(cls):
""" """
Get a dict of annotations to make available for sorting. Get a dict of annotations to make available for sorting.
""" """
@ -1613,15 +1613,32 @@ class DomainRequestExport(BaseExport):
def get_filtered_domain_requests_by_org(domain_requests_to_filter, org_to_filter_by): def get_filtered_domain_requests_by_org(domain_requests_to_filter, org_to_filter_by):
"""Returns a list of Domain Requests that has been filtered by the given organization value""" """Returns a list of Domain Requests that has been filtered by the given organization value"""
return domain_requests_to_filter.filter( annotated_queryset = domain_requests_to_filter.annotate(
# Filter based on the generic org value returned by converted_generic_org_type converted_generic_org_type=Case(
id__in=[ # Recreate the logic of the converted_generic_org_type property
domainRequest.id # here in annotations
for domainRequest in domain_requests_to_filter When(
if domainRequest.converted_generic_org_type portfolio__isnull=False,
and domainRequest.converted_generic_org_type == org_to_filter_by then=F("portfolio__organization_type")
] ),
) default=F("generic_org_type"),
output_field=CharField(),
)
)
return annotated_queryset.filter(converted_generic_org_type=org_to_filter_by)
# return domain_requests_to_filter.filter(
# # Filter based on the generic org value returned by converted_generic_org_type
# id__in=[
# domainRequest.id
# for domainRequest in domain_requests_to_filter
# if domainRequest.converted_generic_org_type
# and domainRequest.converted_generic_org_type == org_to_filter_by
# ]
# )
@classmethod @classmethod
def get_computed_fields(cls, delimiter=", ", **kwargs): def get_computed_fields(cls, delimiter=", ", **kwargs):