Skip to content
Open
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,57 @@
# Generated by Django 5.1.15 on 2026-01-26 10:58
__license__ = """
SPDX-FileCopyrightText: Christian Winger
SPDX-License-Identifier: AGPL-3.0-or-later
""" # noqa: 501

import logging

from django.db import migrations
from django.db.models import Count, Max

logger = logging.getLogger("oeplatform")


def remove_duplicate_views(apps, schema_editor):
"""remove duplicates of (table, type, name).

But keep last instance
"""

View = apps.get_model("dataedit", "View")

duplicate_groups = (
View.objects.values("table", "type", "name") # group by
.annotate(keep_id=Max("id"), count=Count("id"))
.filter(count__gt=1)
)

for d in duplicate_groups:
for view in View.objects.filter(
table=d["table"],
type=d["type"],
name=d["name"],
).exclude(id=d["keep_id"]):
logging.warning(f"removing view: {view}")
view.delete()


def remove_duplicate_views_reverse(apps, schema_editor):
# do nothing
pass


class Migration(migrations.Migration):
atomic = False

dependencies = [
("dataedit", "0045_alter_embargo_table"),
]

operations = [
migrations.RunPython(remove_duplicate_views, remove_duplicate_views_reverse),
migrations.AlterUniqueTogether(
name="view",
unique_together={("table", "type", "name")},
),
]
35 changes: 30 additions & 5 deletions dataedit/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

from django.contrib.postgres.search import SearchVectorField
from django.core.exceptions import ValidationError
from django.db import models
from django.db import models, transaction
from django.db.models import (
BooleanField,
CharField,
Expand Down Expand Up @@ -370,7 +370,6 @@ def get_readable_table_name(self) -> str:
)

except Exception:

return self.name

def validate_open_data_license(
Expand Down Expand Up @@ -511,6 +510,33 @@ class View(models.Model):
def __str__(self):
return '{}--"{}"({})'.format(self.table, self.name, self.type.upper())

class Meta:
unique_together = [("table", "type", "name")]

@classmethod
def get_or_create_default(
cls, table: str, type: str = "table", name: str = "default"
) -> "View":
with transaction.atomic():
# technically, multiple views per table can be default (or none).
view = View.objects.filter(is_default=True, table=table).last()
if view:
return view
# its possible that we have a view named "default", that is not
# marked as is_default=True
view = View.objects.filter(table=table, type=type, name=name).last()
if view is not None:
# make it default for next time
view.is_default = True
view.save()
return view

# create a new one
view = View.objects.create(
table=table, type=type, name=name, is_default=True
)
return view


class Filter(models.Model):
column = CharField(max_length=100, null=False)
Expand Down Expand Up @@ -708,13 +734,12 @@ def set_version_of_metadata_for_review(self, table: str, *args, **kwargs):

return (
True,
f"Set current version of table's: '{table}' " "oemetadata for review.",
f"Set current version of table's: '{table}' oemetadata for review.",
)

return (
False,
f"This tables (name: {table}) review "
"already got a version of oemetadata.",
f"This tables (name: {table}) review already got a version of oemetadata.",
)

def update_all_table_peer_reviews_after_table_moved(self, *args, topic, **kwargs):
Expand Down
12 changes: 8 additions & 4 deletions dataedit/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,18 @@
name="table-view-save",
),
re_path(
r"^(?P<table>{qual})/view/set-default".format(qual=pgsql_qualifier),
# TODO: not used yet
r"^(?P<table>{qual})/view/(?P<view_id>{qual})/set-default".format(
qual="[0-9]+"
),
table_view_set_default_view,
name="table-view-set-default", # TODO: should be POST, but is GET?
name="table-view-set-default",
),
re_path(
r"^(?P<table>{qual})/view/delete".format(qual=pgsql_qualifier),
# TODO: not used yet
r"^(?P<table>{qual})/view/(?P<view_id>{qual})/delete".format(qual="[0-9]+"),
table_view_delete_view,
name="table-view-delete-default", # TODO: should be POST, but is GET?
name="table-view-delete-default",
),
re_path(
r"^(?P<table>{qual})/graph/new".format(qual=pgsql_qualifier),
Expand Down
42 changes: 18 additions & 24 deletions dataedit/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import re
from collections import defaultdict
from io import TextIOWrapper
from itertools import chain

from django.contrib import messages
from django.contrib.auth.decorators import login_required
Expand Down Expand Up @@ -529,28 +528,28 @@ def table_view_save_view(request: HttpRequest, table: str) -> HttpResponse:
)


def table_view_set_default_view(request: HttpRequest, table: str) -> HttpResponse:
@require_POST
def table_view_set_default_view(
request: HttpRequest, table: str, view_id: int
) -> HttpResponse:
table_obj = table_or_404(table=table)

# TODO: shouldnt this be POST only?
post_id = request.GET.get("id")

for view in DBView.objects.filter(table=table_obj.name):
if str(view.pk) == post_id:
if str(view.pk) == view_id:
view.is_default = True
else:
view.is_default = False
view.save()
return redirect("dataedit:view", table=table_obj.name)


def table_view_delete_view(request: HttpRequest, table: str) -> HttpResponse:
@require_POST
def table_view_delete_view(
request: HttpRequest, table: str, view_id: int
) -> HttpResponse:
table_obj = table_or_404(table=table)

# TODO: shouldnt this be POST only?
post_id = request.GET.get("id")

view = DBView.objects.get(id=post_id, table=table_obj.name)
view = DBView.objects.get(pk=view_id, table=table_obj.name)
view.delete()

return redirect("dataedit:view", table=table_obj.name)
Expand Down Expand Up @@ -684,7 +683,7 @@ def iter_oem_key_order(metadata: dict):
table_label = table_obj.human_readable_name

table_views = DBView.objects.filter(table=table)
default = DBView(name="default", type="table", table=table)
default_view = DBView.get_or_create_default(table=table)
view_id = request.GET.get("view")

embargo = Embargo.objects.filter(table=table_obj).first()
Expand All @@ -697,18 +696,13 @@ def iter_oem_key_order(metadata: dict):
else:
embargo_time_left = "No embargo data available"

if view_id == "default":
current_view = default
current_view.save()
else:
try:
# at first, try to use the view, that is passed as get argument
current_view = table_views.get(id=view_id)
except ObjectDoesNotExist:
current_view = default
current_view.save()

table_views = list(chain((default,), table_views))
try:
# at first, try to use the view, that is passed as get argument
current_view = table_views.get(id=view_id)
except ObjectDoesNotExist:
current_view = default_view

table_views = [default_view, *table_views.exclude(pk=default_view.pk)]

#########################################################
# Get open peer review process related metadata #
Expand Down