Skip to content

Commit

Permalink
refactor(apis_relations): drop custom table factory
Browse files Browse the repository at this point in the history
This commit drops the `get_generic_triple_table` method that was used to
generate the table classes for the triple tables in the edit and the
detail view. For the edit and the detail view there are now the templatetags
`triple_tables_related_detail` and `triple_tables_related_edit` which
provide those tables.
The `generic_order*` and `generic_render*` methods that were located in
the `apis_metainfo.tables` module where dropped and replaced by custom
table columns `StartDateColumn` and `EndDateColumn`.
  • Loading branch information
b1rger committed Mar 4, 2024
1 parent 5672ea9 commit 3ae7c3d
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 350 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{% extends "apis_core/apis_entities/abstractentity.html" %}
{% load django_tables2 %}
{% load apis_templatetags %}
{% load apis_relations %}

{% block col-zero %}
<div class="card">
Expand All @@ -11,14 +11,9 @@
{% block col-one %}
<div class="card">
<div class="card-body">
{% object_relations as object_relations %}
{% for rel in object_relations %}

{% if rel.1.data|length > 0 %}
<h5>{{ rel.0|title }}</h5>
<div id="tab_{{ rel.2 }}">{% render_table rel.1 %}</div>
{% endif %}

{% for objecttype, table in object|triple_tables_related_detail %}
<h5>{{ objecttype.name|title }}</h5>
<div id="tab_{{ objecttype }}">{% render_table table %}</div>
{% endfor %}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,10 @@
})
}
</script>
{% object_relations as object_relations %}
<script type="text/javascript">
function activate_editing(){
{% for obj in object_relations %}
GetFormAjax("{{obj.2}}");
//unbind_ajax_forms();
{% for triple_form_type in object|triple_form_types %}
GetFormAjax("{{triple_form_type}}");
{% endfor %}
};
activate_editing();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
{% load django_tables2 %}
{% load apis_templatetags %}
{% object_relations detail=False as object_relations %}
{% for obj in object_relations %}
<div class="card card-default mb-2">
<div class="card-header" role="tab" id="heading{{ forloop.counter }}">
<div class="card-title">
<a data-toggle="collapse" href="#collapse{{ forloop.counter }}">{{ obj.0|title }} ({{ obj.1.data|length }})</a>
{% load apis_relations %}
{% load apiscore %}
{% with object|opts as opts %}
{% for objecttype, table in object|triple_tables_related_edit %}
<div class="card card-default mb-2">
<div class="card-header" role="tab" id="heading{{ forloop.counter }}">
<div class="card-title">
<a data-toggle="collapse" href="#collapse{{ forloop.counter }}">{{ objecttype.name|title }} ({{ table.data|length }})</a>
</div>
</div>
<div id="collapse{{ forloop.counter }}" class="card-collapse collapse">
<div id="tab_triple_form_{{ opts.verbose_name }}_to_{{ objecttype.name }}"
class="card-body">{% render_table table %}</div>
</div>
</div>
<div id="collapse{{ forloop.counter }}" class="card-collapse collapse
{% if obj.3 %}in{% endif %}
">
<div id="tab_{{ obj.2 }}" class="card-body">{% render_table obj.1 %}</div>
</div>
</div>
{% endfor %}
{% endfor %}
{% endwith %}
23 changes: 16 additions & 7 deletions apis_core/apis_entities/templatetags/apis_templatetags.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from operator import itemgetter
from django import template
from apis_core.utils import caching
from apis_core.utils.helpers import triple_sidebar
from apis_core.utils.helpers import get_classes_with_allowed_relation_from

register = template.Library()

Expand Down Expand Up @@ -35,9 +35,18 @@ def entities_list_links():
return entities_links


@register.simple_tag(takes_context=True)
def object_relations(context, detail=True):
obj = context["object"]
return triple_sidebar(
obj.pk, obj.__class__.__name__.lower(), context["request"], detail
)
@register.filter
def triple_form_types(instance):
"""
This is a helper function to generate identifiers which
are then used in `abstractentity_form.html` in the javascript
part to initialize the old triple tables and forms.
"""
entity_name = instance._meta.verbose_name
object_relations = []
for entity_class in get_classes_with_allowed_relation_from(entity_name):
other_entity_class_name = entity_class.__name__.lower()
object_relations.append(
f"triple_form_{entity_name}_to_{other_entity_class_name}"
)
return object_relations
98 changes: 0 additions & 98 deletions apis_core/apis_metainfo/tables.py
Original file line number Diff line number Diff line change
@@ -1,105 +1,7 @@
import django_tables2 as tables
from django.db.models import F
from django.utils.html import format_html

from .models import Uri


# generic order_FOO methods for start_date_written and end_date_written to be used in all kinds of tables where a queryset is loaded
# whose model has start_date_written and end_date_written. These methods order the *_date_written by their corresponding
# parsed date objects.
#
# In order to use them in a table using django-tables2, the table class must be assigned *_date_written columns
# (either through fields in Meta inner class or through custom Column() definitions).
# Important however is that the names between the columns and the order methods are correlated to each other.
#
# The django-tables2 plugin searches for each column through the table class for corresponding order_* and render_* methods
# E.g. to define custom ordering and rendering for a field column 'name' the table class must have
# 'order_name' and 'render_name' methods. This approach is called order_FOO and render_FOO by django-tables2.
#
# So in order to use these functions here, define within the table class
# 1.) the respective column
# 2.) a correspondingly named method for each column
# 3.) assign to this method one of the two functions below
#
# In the case of e.g. start_date_written,
# the table class thus must have a method / class variable 'order_start_date_written = generic_order_start_date_written'


def generic_order_start_date_written(self, queryset, is_descending):
if is_descending:
queryset = queryset.order_by(
F("start_date").desc(nulls_last=True)
) # nulls_last=True puts null values behind non-null values
else:
queryset = queryset.order_by(F("start_date").asc(nulls_last=True))

return (queryset, True)


def generic_order_end_date_written(self, queryset, is_descending):
if is_descending:
queryset = queryset.order_by(F("end_date").desc(nulls_last=True))
else:
queryset = queryset.order_by(F("end_date").asc(nulls_last=True))

return (queryset, True)


def helper_render_date(value, var_date, var_start_date, var_end_date):
"""
helper function to avoid duplicated code. It checks the various sub-dates of a model's date field for them being None
or having values. If a field is None then check for the next, and if all are None, return '—' inditcating no value.
If there are values, use them as mouse overlay helptext to inform the user about the parsing result behind a written
date field.
:param value: str : the *_date_written (either start_date_written or end_date_written) field of an entity or relation
:param var_date: datetime : either the precisely parsed date or the average in between two dates when *_date_written is a range
:param var_start_date: datetime : The sub-date of var_date, indicating the start date of the range
:param var_end_date: datetime : The sub-date of var_date, indicating the end date of the range
:return: html string : which has the value of the written date and the parsed dates as mouse overlay helptext
"""

# Various if-else branches checking which of the date fields are not None and should be used

if var_start_date is not None and var_end_date is not None:

overlay_help_text = str(var_start_date) + " - " + str(var_end_date)

elif var_date is not None:

overlay_help_text = str(var_date)

else:

return "—"

return format_html("<abbr title='" + overlay_help_text + "'>" + value + "</b>")


# Again this function serves a generic purpose and must be assigned as class method to django-tables2 tables.Table class
# The whole logic is very similare to the generic_order_* functions above, so see their comments for more details.
def generic_render_start_date_written(self, record, value):

return helper_render_date(
value=value,
var_date=record.start_date,
var_start_date=record.start_start_date,
var_end_date=record.start_end_date,
)


def generic_render_end_date_written(self, record, value):

return helper_render_date(
value=value,
var_date=record.end_date,
var_start_date=record.end_start_date,
var_end_date=record.end_end_date,
)


class UriTable(tables.Table):
id = tables.LinkColumn()
entity = tables.TemplateColumn(
Expand Down
32 changes: 13 additions & 19 deletions apis_core/apis_relations/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from dal import autocomplete
from django import forms
from django.conf import settings
from django.db.models import Q
from django.urls import reverse

from apis_core.apis_relations.models import TempTriple
Expand All @@ -13,10 +12,12 @@

from apis_core.apis_metainfo.models import Uri

from .tables import get_generic_triple_table
from apis_core.apis_entities.autocomplete3 import (
PropertyAutocomplete,
)
from apis_core.generic.helpers import first_match_via_mro
from apis_core.apis_relations.tables import TempTripleEditTable
from apis_core.utils.helpers import triples_related


class GenericTripleForm(forms.ModelForm):
Expand Down Expand Up @@ -191,24 +192,17 @@ def get_text_id(self):
return self.cleaned_data["HL_text_id"][5:]

def get_html_table(self, entity_instance_self, entity_instance_other):
table_class = get_generic_triple_table(
other_entity_class_name=entity_instance_other.__class__.__name__.lower(),
entity_pk_self=entity_instance_self.pk,
detail=False,
table_class = (
first_match_via_mro(
entity_instance_self._meta.model,
path="tables",
suffix="TempTripleEditTable",
)
or TempTripleEditTable
)
entity_content_type = ContentType.objects.get_for_model(entity_instance_other)
triples = triples_related(entity_instance_self.pk, entity_content_type)

table_object = table_class(
data=TempTriple.objects.filter(
(
Q(subj__self_contenttype=entity_instance_other.self_contenttype)
& Q(obj=entity_instance_self)
)
| (
Q(obj__self_contenttype=entity_instance_other.self_contenttype)
& Q(subj=entity_instance_self)
)
),
prefix=entity_instance_other.__class__.__name__,
)
table_object = table_class(data=triples, instance=entity_instance_self)

return table_object
Loading

0 comments on commit 3ae7c3d

Please sign in to comment.