Maybe hack-y but working custom field serialization

This commit is contained in:
shamoon 2023-10-31 10:47:31 -07:00
parent 9b953f3dd6
commit 17abd90c46
3 changed files with 47 additions and 32 deletions

View File

@ -1,4 +1,4 @@
# Generated by Django 4.2.5 on 2023-10-28 02:54 # Generated by Django 4.2.5 on 2023-10-31 17:28
import django.db.models.deletion import django.db.models.deletion
import django.utils.timezone import django.utils.timezone
@ -92,16 +92,6 @@ class Migration(migrations.Migration):
to="documents.customfield", to="documents.customfield",
), ),
), ),
(
"owner",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
to=settings.AUTH_USER_MODEL,
verbose_name="owner",
),
),
], ],
options={ options={
"verbose_name": "custom field instance", "verbose_name": "custom field instance",
@ -229,4 +219,11 @@ class Migration(migrations.Migration):
), ),
], ],
), ),
migrations.AddConstraint(
model_name="customfieldinstance",
constraint=models.UniqueConstraint(
fields=("document", "field"),
name="documents_customfieldinstance_unique_document_field",
),
),
] ]

View File

@ -4,6 +4,7 @@ import os
import re import re
from collections import OrderedDict from collections import OrderedDict
from pathlib import Path from pathlib import Path
from typing import Any
from typing import Final from typing import Final
from typing import Optional from typing import Optional
@ -920,7 +921,7 @@ class CustomField(models.Model):
return f"{self.name} : {self.data_type}" return f"{self.name} : {self.data_type}"
class CustomFieldInstance(ModelWithOwner): class CustomFieldInstance(models.Model):
""" """
A single instance of a field, attached to a CustomField for the name and type A single instance of a field, attached to a CustomField for the name and type
and attached to a single Document to be metadata for it and attached to a single Document to be metadata for it
@ -952,6 +953,12 @@ class CustomFieldInstance(ModelWithOwner):
ordering = ("created",) ordering = ("created",)
verbose_name = _("custom field instance") verbose_name = _("custom field instance")
verbose_name_plural = _("custom field instances") verbose_name_plural = _("custom field instances")
constraints = [
models.UniqueConstraint(
fields=["document", "field"],
name="%(app_label)s_%(class)s_unique_document_field",
),
]
def __str__(self) -> str: def __str__(self) -> str:
return str(self.field) + f" : {self.value}" return str(self.field) + f" : {self.value}"
@ -1002,17 +1009,19 @@ class CustomFieldInstance(ModelWithOwner):
@staticmethod @staticmethod
def from_json( def from_json(
document: Document, document: Document,
field: CustomField, field: OrderedDict,
data, value: Any,
) -> "CustomFieldInstance": ) -> "CustomFieldInstance":
instance = CustomFieldInstance.objects.create( instance, _ = CustomFieldInstance.objects.get_or_create(
document=document, document=document,
field=field, field=CustomField.objects.get(id=field["id"]),
data_type=data["type"], )
instance.field_type.objects.update_or_create(
parent=instance,
defaults={"value": value},
) )
instance.field_type.objects.create(value=data["value"], parent=instance)
return field return instance
class CustomFieldShortText(models.Model): class CustomFieldShortText(models.Model):

View File

@ -2,6 +2,7 @@ import datetime
import math import math
import re import re
import zoneinfo import zoneinfo
from typing import Any
import magic import magic
from celery import states from celery import states
@ -406,26 +407,16 @@ class CustomFieldSerializer(serializers.ModelSerializer):
] ]
class CustomFieldInstanceSerializer(serializers.ModelSerializer): class CustomFieldInstanceSerializer(serializers.Serializer):
parent = CustomFieldSerializer() field = CustomFieldSerializer(required=True)
value = SerializerMethodField() value = SerializerMethodField()
def get_value(self, obj: CustomFieldInstance): def get_value(self, obj: CustomFieldInstance):
return obj.value return obj.value
def create(self, validated_data):
parent_data = validated_data.pop("parent")
parent = CustomField.objects.get(id=parent_data["id"])
instance = CustomFieldInstance.objects.create(parent=parent)
return instance
def update(self, instance: CustomFieldInstance):
return instance
class Meta: class Meta:
model = CustomFieldInstance
fields = [ fields = [
"parent", "field",
"value", "value",
] ]
@ -463,7 +454,25 @@ class DocumentSerializer(OwnedObjectSerializer, DynamicFieldsModelSerializer):
doc["content"] = doc.get("content")[0:550] doc["content"] = doc.get("content")[0:550]
return doc return doc
def to_internal_value(self, data: Any) -> Any:
# hack-y
values = super().to_internal_value(data)
if "custom_fields" in values:
for index, field_instance in enumerate(values["custom_fields"]):
data_custom_field = data["custom_fields"][index]
field_instance["field"]["id"] = data_custom_field["field"]["id"]
field_instance["value"] = data_custom_field["value"]
return values
def update(self, instance, validated_data): def update(self, instance, validated_data):
if "custom_fields" in validated_data:
custom_fields = validated_data.pop("custom_fields")
for field_data in custom_fields:
CustomFieldInstance.from_json(
document=instance,
field=field_data["field"],
value=field_data["value"],
)
if "created_date" in validated_data and "created" not in validated_data: if "created_date" in validated_data and "created" not in validated_data:
new_datetime = datetime.datetime.combine( new_datetime = datetime.datetime.combine(
validated_data.get("created_date"), validated_data.get("created_date"),