Skip to content

Commit

Permalink
Merge pull request #139 from maykinmedia/feature/records-with-index
Browse files Browse the repository at this point in the history
Feature/records with index
  • Loading branch information
annashamray committed Jan 13, 2021
2 parents 194a3d3 + e8c7079 commit 0ae80f2
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 89 deletions.
39 changes: 27 additions & 12 deletions src/objects/api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
from django.db import transaction
from django.utils.translation import ugettext_lazy as _

from rest_framework import serializers
from rest_framework_gis.serializers import GeometryField

from objects.core.models import Object, ObjectRecord

from .validators import CorrectionValidator, IsImmutableValidator, JsonSchemaValidator
from .validators import IsImmutableValidator, JsonSchemaValidator


class ObjectSlugRelatedField(serializers.SlugRelatedField):
def get_queryset(self):
queryset = ObjectRecord.objects.all()

object_instance = self.parent.parent.instance
if not object_instance:
return queryset.none()

return queryset.filter(object=object_instance)


class ObjectRecordSerializer(serializers.ModelSerializer):
correctionFor = serializers.SlugRelatedField(
correctionFor = ObjectSlugRelatedField(
source="correct",
slug_field="uuid",
queryset=ObjectRecord.objects.all(),
slug_field="index",
required=False,
help_text=_("Index of the record corrected by the current record"),
)
correctedBy = serializers.SlugRelatedField(
source="corrected",
slug_field="uuid",
slug_field="index",
read_only=True,
help_text=_("Index of the record, which corrects the current record"),
)

class Meta:
model = ObjectRecord
fields = (
"uuid",
"index",
"typeVersion",
"data",
"geometry",
Expand All @@ -35,7 +48,7 @@ class Meta:
"correctedBy",
)
extra_kwargs = {
"uuid": {"read_only": True},
"index": {"read_only": True},
"typeVersion": {"source": "version"},
"startAt": {"source": "start_at"},
"endAt": {"source": "end_at", "read_only": True},
Expand All @@ -46,19 +59,21 @@ class Meta:
class HistoryRecordSerializer(serializers.ModelSerializer):
correctionFor = serializers.SlugRelatedField(
source="correct",
slug_field="uuid",
slug_field="index",
read_only=True,
help_text=_("Index of the record corrected by the current record"),
)
correctedBy = serializers.SlugRelatedField(
source="corrected",
slug_field="uuid",
slug_field="index",
read_only=True,
help_text=_("Index of the record, which corrects the current record"),
)

class Meta:
model = ObjectRecord
fields = (
"uuid",
"index",
"typeVersion",
"data",
"geometry",
Expand All @@ -69,7 +84,7 @@ class Meta:
"correctedBy",
)
extra_kwargs = {
"uuid": {"read_only": True},
"index": {"read_only": True},
"typeVersion": {"source": "version"},
"startAt": {"source": "start_at"},
"endAt": {"source": "end_at", "read_only": True},
Expand All @@ -87,7 +102,7 @@ class Meta:
"url": {"lookup_field": "uuid"},
"type": {"source": "object_type", "validators": [IsImmutableValidator()]},
}
validators = [JsonSchemaValidator(), CorrectionValidator()]
validators = [JsonSchemaValidator()]

def to_representation(self, instance):
ret = super().to_representation(instance)
Expand Down
19 changes: 0 additions & 19 deletions src/objects/api/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,6 @@ def __call__(self, attrs):
raise serializers.ValidationError(exc.args[0], code=self.code) from exc


class CorrectionValidator:
message = _("Only records of the same objects can be corrected")
code = "invalid-correction"

def set_context(self, serializer):
"""
This hook is called by the serializer instance,
prior to the validation call being made.
"""
self.instance = getattr(serializer, "instance", None)

def __call__(self, attrs):
record = attrs.get("current_record", {})
correct = record.get("correct")

if correct and correct.object != self.instance:
raise serializers.ValidationError(self.message, code=self.code)


class IsImmutableValidator:
"""
Validate that the field should not be changed in update action
Expand Down
6 changes: 3 additions & 3 deletions src/objects/core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
class ObjectRecordInline(admin.TabularInline):
model = ObjectRecord
extra = 1
readonly_fields = ("uuid", "registration_at", "end_at", "get_corrected_by")
search_fields = ("uuid",)
readonly_fields = ("index", "registration_at", "end_at", "get_corrected_by")
fields = (
"index",
"version",
"data",
"geometry",
"start_at",
"end_at",
"registration_date",
"registration_at",
"get_corrected_by",
"correct",
)
Expand Down
24 changes: 24 additions & 0 deletions src/objects/core/migrations/0018_auto_20210113_1239.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 2.2.12 on 2021-01-13 11:39

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("core", "0017_auto_20210111_1653"),
]

operations = [
migrations.RemoveField(
model_name="objectrecord",
name="uuid",
),
migrations.AddField(
model_name="objectrecord",
name="index",
field=models.PositiveIntegerField(
default=1, help_text="Incremental index number of the object record."
),
),
]
32 changes: 32 additions & 0 deletions src/objects/core/migrations/0019_fill_record_index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from django.db import migrations
from django.db.models.expressions import Window
from django.db.models.functions import RowNumber
from django.db.models import F


def fill_record_index(apps, _):
ObjectRecord = apps.get_model("core", "ObjectRecord")

records = ObjectRecord.objects.annotate(
row_number=Window(
expression=RowNumber(),
partition_by=[F("object")],
order_by=[F("start_at"), F("id")],
)
).order_by("object")

for record in records:
if record.index != record.row_number:
record.index = record.row_number
record.save()


class Migration(migrations.Migration):

dependencies = [
("core", "0018_auto_20210113_1239"),
]

operations = [
migrations.RunPython(fill_record_index, migrations.RunPython.noop),
]
11 changes: 7 additions & 4 deletions src/objects/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ def last_record(self):


class ObjectRecord(models.Model):
# index = models.PositiveIntegerField(help_text="Incremental index number of the object record.", default=1)
uuid = models.UUIDField(
default=uuid.uuid4, help_text="Unique identifier (UUID4)", unique=True
index = models.PositiveIntegerField(
default=1,
help_text=_("Incremental index number of the object record."),
)
object = models.ForeignKey(Object, on_delete=models.CASCADE, related_name="records")
version = models.PositiveSmallIntegerField(
Expand Down Expand Up @@ -87,6 +87,9 @@ class ObjectRecord(models.Model):
),
)

class Meta:
unique_together = ("object", "index")

def __str__(self):
return f"{self.version} ({self.start_at})"

Expand All @@ -97,7 +100,7 @@ def clean(self):

def save(self, *args, **kwargs):
if not self.id and self.object.last_record:
# self.index = self.object.last_record.index + 1
self.index = self.object.last_record.index + 1

# add end_at to previous record
previous_record = self.object.last_record
Expand Down

0 comments on commit 0ae80f2

Please sign in to comment.