Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ms/simple management command for ng relation classes #1097

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import os
from django.core.management.base import BaseCommand
from django.db.models.query import QuerySet
from django.conf import settings

from apis_core.apis_relations.models import Property


def to_camel_case(value):
content = "".join(value.title().split())
return content[0].lower() + content[1:]


def format_classes(value):
if isinstance(value, QuerySet):
if value.count() == 1:
return value.first().model_class().__name__
return "[" + ", ".join([format_classes(v) for v in value]) + "]"
else:
return value.model_class().__name__


template = """
class {relation_class}(Relation{additional_base_classes}):
\"\"\"automatically generated class from property with id {prop_id}\"\"\"

subj_model = {subj_model}
obj_model = {obj_model}

review = models.BooleanField(
default=False,
help_text="Should be set to True, if the data record holds up quality standards.",
)
start_date = models.DateField(blank=True, null=True)
start_start_date = models.DateField(blank=True, null=True)
start_end_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
end_start_date = models.DateField(blank=True, null=True)
end_end_date = models.DateField(blank=True, null=True)
start_date_written = models.CharField(
max_length=255,
blank=True,
null=True,
verbose_name="Start",
)
end_date_written = models.CharField(
max_length=255,
blank=True,
null=True,
verbose_name="End",
)
status = models.CharField(max_length=100)
references = models.TextField(blank=True, null=True)
notes = models.TextField(blank=True, null=True)

@classmethod
def name(self) -> str:
return "{relation_label}"

@classmethod
def reverse_name(self) -> str:
return "{reverse_relation_label}"
"""


class Command(BaseCommand):
help = "Run through existing relations and create ng relation classes from the properties."

def add_arguments(self, parser):
parser.add_argument(
"--file", type=str, help="File to write the new relation classes to."
)
parser.add_argument(
"--auto_format",
action="store_true",
help="Whether to auto format the file using ruff (dependency needs to be available).",
)

def handle(self, *args, **options):
classes = []
for prop in Property.objects.all():
classes.append(
template.format(
relation_class=to_camel_case(prop.name_forward),
additional_base_classes=", VersionMixin"
if "apis_core.history" in settings.INSTALLED_APPS
else "",
prop_id=prop.id,
subj_model=format_classes(prop.subj_class.all()),
obj_model=format_classes(prop.obj_class.all()),
relation_label=prop.name_forward,
reverse_relation_label=prop.name_reverse,
)
)
if options["file"]:
with open(options["file"], "r") as of:
with open(options["file"] + ".tmp", "w") as f:
f.write("from apis_core.relations.models import Relation\n")
f.write(of.read())
f.write(
"\n################################################\n#auto generated relation classes from properties\n################################################\n"
)
f.write("\n\n".join(classes))
f.seek(0)
os.remove(options["file"])
os.rename(options["file"] + ".tmp", options["file"])
if options["auto_format"]:
try:
import ruff

ruff.format_file(options["file"])
ruff.isort_file(options["file"])
except ImportError:
print(
"Auto formatting not possible, ruff not available. Please install ruff."
)
17 changes: 17 additions & 0 deletions docs/source/ontology.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,20 @@ Now you can create instances of that relation on your entity pages.
This new module does not change any code in the existing datamodel or codebase. This
prevents existing projects that use the legacy Triple or TempTriple implementation
to break.


Upgrade from Triple to Relations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you have an existing project that uses the legacy Triple or TempTriple implementation
you can upgrade to the new Relations module. The upgrade is not automatic, but we provide
a management command that will add new relation classes to your `models.py`.

.. code-block:: bash

python manage.py upgrade_triples_to_relations --file=MODELS_FILE_TO_UPGRADE --auto_format

The `--file` argument is required and should point to the `models.py` file that you want
to upgrade. The `--auto_format` argument is optional and will automatically format the
`models.py` file after the upgrade using ruff. If you don't provide this argument or dont
have ruff installed you will have to format the file yourself.
Loading