-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrefdata_fields.py
110 lines (86 loc) · 3.65 KB
/
refdata_fields.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
"""Reference data fields listing
Helper script that prints a markdown table containing
fields that accept reference data.
Used for generating the table in `docs/user-guide/reference-data.md`.
"""
import os
import sys
from typing import Dict
import django
sys.path.append("./src")
os.environ["DJANGO_SETTINGS_MODULE"] = "metax_service.settings"
django.setup()
from rest_framework import serializers
from rest_framework.reverse import reverse
from apps.common.serializers import URLReferencedModelField, URLReferencedModelListField
from apps.core.serializers import (
DataCatalogModelSerializer,
DatasetSerializer,
LicenseModelSerializer,
)
from apps.core.serializers.dataset_actor_serializers.organization_serializer import (
DatasetOrganizationSerializer,
)
from apps.files.helpers import get_file_metadata_serializer
from apps.files.serializers.file_serializer import FileSerializer
from apps.refdata.models import License
from apps.refdata.serializers import BaseRefdataSerializer
def get_url(serializer):
model_name = serializer.Meta.model._meta.object_name.lower()
return reverse(f"{model_name}-list")
extra_refdata_serializers = {
DatasetOrganizationSerializer: reverse(f"organization-list"),
LicenseModelSerializer: get_url(License.get_serializer_class()()),
}
def get_refdata_fields(serializer: serializers.Serializer, path="") -> Dict[str, str]:
"""Get mapping of field path -> reference data url."""
nested_fields = {}
def recurse(field, path=""):
found = False
for extra_serializer, serializer_url in extra_refdata_serializers.items():
if isinstance(field, extra_serializer):
nested_fields[path] = serializer_url
found = True
break
if found:
return
elif isinstance(field, BaseRefdataSerializer):
nested_fields[path] = get_url(field)
elif isinstance(field, serializers.Serializer):
for key, subfield in field.fields.items():
key_path = key if path == "" else f"{path}.{key}"
if isinstance(subfield, URLReferencedModelListField):
recurse(subfield.child, path=key_path + "[]")
elif isinstance(subfield, URLReferencedModelField):
recurse(subfield.child, path=key_path)
if isinstance(subfield, serializers.ListSerializer):
recurse(subfield.child, path=key_path + "[]")
elif isinstance(subfield, serializers.Serializer):
recurse(subfield, path=key_path)
recurse(serializer, path=path)
return nested_fields
class DummyView:
query_params = {}
context = {"view": DummyView()}
# map refdata field -> url
fields = {}
fields.update(get_refdata_fields(DatasetSerializer(context=context), path="Dataset"))
fields.update(get_refdata_fields(DataCatalogModelSerializer(context=context), path="DataCatalog"))
fields.update(get_refdata_fields(FileSerializer(context=context), path="File"))
# File.dataset_metadata is a SerializerMethodField so it doesn't get handled automatically
fields.update(
get_refdata_fields(
get_file_metadata_serializer()(context=context), path="File.dataset_metadata"
)
)
# map refdata url -> field
refdata_fields = {}
for field, path in fields.items():
refdata_fields.setdefault(path, []).append(field)
refdata_fields = {key: refdata_fields[key] for key in sorted(refdata_fields)}
print("<!-- table generated with refdata_fields.py -->")
print("")
print("| Reference data | Used by fields |")
print("|---|---|")
for url, fields in refdata_fields.items():
print(f"| [{url}]({url}) | {'<br>'.join(sorted(fields))} |")