Skip to content

Commit 8052df1

Browse files
committed
[fix] Added fields to the header
1 parent b65df4b commit 8052df1

3 files changed

Lines changed: 62 additions & 3 deletions

File tree

openwisp_users/management/commands/export_users.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ def _normalize_value(value):
2727
"""Convert None to empty string, otherwise stringify the value."""
2828
return "" if value is None else str(value)
2929

30+
@staticmethod
31+
def _get_header(field):
32+
normalized = normalize_field(field)
33+
header = normalized.get("header")
34+
if header:
35+
return header
36+
header_fields = normalized.get("header_fields") or normalized.get("fields")
37+
if header_fields:
38+
return f"{normalized['name']} ({', '.join(header_fields)})"
39+
return normalized["name"]
40+
3041
def add_arguments(self, parser):
3142
parser.add_argument(
3243
"--exclude-fields",
@@ -72,7 +83,7 @@ def handle(self, *args, **options):
7283
with open(filename, "w", newline="", encoding="utf-8") as csv_file:
7384
csv_writer = csv.writer(csv_file)
7485
# Write header row using the name of each field
75-
csv_writer.writerow([normalize_field(f)["name"] for f in fields])
86+
csv_writer.writerow([self._get_header(f) for f in fields])
7687

7788
# Write data rows
7889
for user in queryset.iterator(chunk_size=1000):

openwisp_users/settings.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,11 @@ def export_organizations(user):
4444
"location",
4545
"notes",
4646
"language",
47-
{"name": "organizations", "callable": export_organizations},
47+
{
48+
"name": "organizations",
49+
"header_fields": ["organization_id", "is_admin"],
50+
"callable": export_organizations,
51+
},
4852
],
4953
"select_related": [],
5054
"prefetch_related": ["openwisp_users_organizationuser"],

openwisp_users/tests/test_commands.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def test_export_users(self):
6767
"location",
6868
"notes",
6969
"language",
70-
"organizations",
70+
"organizations (organization_id, is_admin)",
7171
]
7272
self.assertEqual(csv_data[0], expected_headers)
7373
# Ensuring ordering
@@ -265,6 +265,16 @@ def test_subfields_dict_field(self):
265265
csv_data = list(csv_reader)
266266
# 2 users + 1 header
267267
self.assertEqual(len(csv_data), 3)
268+
expected_headers = [
269+
"id",
270+
"auth_token (key)",
271+
"auth_token (key, created)",
272+
"birth_date (year)",
273+
"openwisp_users_organizationuser (organization_id)",
274+
"openwisp_users_organizationuser (organization_id, is_admin)",
275+
"openwisp_users_organizationuser.organization_id",
276+
]
277+
self.assertEqual(csv_data[0], expected_headers)
268278
# user1: token present, birth_date None, one org membership
269279
self.assertEqual(csv_data[1][0], str(user1.id))
270280
# subfields, single obj
@@ -318,3 +328,37 @@ def test_plain_relation_field_returns_empty_string(self):
318328
self._create_org_user(organization=org, user=user, is_admin=True)
319329
result = Command()._get_field_value(user, "openwisp_users_organizationuser")
320330
self.assertEqual(result, "")
331+
332+
@capture_stdout()
333+
def test_custom_header(self):
334+
def _get_is_active(user):
335+
return "yes" if user.is_active else "no"
336+
337+
config = {
338+
"fields": [
339+
"id",
340+
{
341+
"name": "active_status",
342+
"header": "Active?",
343+
"callable": _get_is_active,
344+
},
345+
{
346+
"name": "custom_orgs",
347+
"header_fields": ["org_id", "is_admin"],
348+
"callable": _get_is_active,
349+
},
350+
],
351+
"select_related": [],
352+
"prefetch_related": [],
353+
}
354+
self._create_user(is_active=True)
355+
with patch.object(app_settings, "EXPORT_USERS_COMMAND_CONFIG", config):
356+
call_command("export_users", filename=self.temp_file.name)
357+
with open(self.temp_file.name, "r", encoding="utf-8") as f:
358+
csv_reader = csv.reader(f)
359+
csv_data = list(csv_reader)
360+
self.assertEqual(
361+
csv_data[0], ["id", "Active?", "custom_orgs (org_id, is_admin)"]
362+
)
363+
self.assertEqual(csv_data[1][1], "yes")
364+
self.assertEqual(csv_data[1][2], "yes")

0 commit comments

Comments
 (0)