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.utils.timezone
@ -92,16 +92,6 @@ class Migration(migrations.Migration):
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={
"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
from collections import OrderedDict
from pathlib import Path
from typing import Any
from typing import Final
from typing import Optional
@ -920,7 +921,7 @@ class CustomField(models.Model):
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
and attached to a single Document to be metadata for it
@ -952,6 +953,12 @@ class CustomFieldInstance(ModelWithOwner):
ordering = ("created",)
verbose_name = _("custom field instance")
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:
return str(self.field) + f" : {self.value}"
@ -1002,17 +1009,19 @@ class CustomFieldInstance(ModelWithOwner):
@staticmethod
def from_json(
document: Document,
field: CustomField,
data,
field: OrderedDict,
value: Any,
) -> "CustomFieldInstance":
instance = CustomFieldInstance.objects.create(
instance, _ = CustomFieldInstance.objects.get_or_create(
document=document,
field=field,
data_type=data["type"],
field=CustomField.objects.get(id=field["id"]),
)
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):

View File

@ -2,6 +2,7 @@ import datetime
import math
import re
import zoneinfo
from typing import Any
import magic
from celery import states
@ -406,26 +407,16 @@ class CustomFieldSerializer(serializers.ModelSerializer):
]
class CustomFieldInstanceSerializer(serializers.ModelSerializer):
parent = CustomFieldSerializer()
class CustomFieldInstanceSerializer(serializers.Serializer):
field = CustomFieldSerializer(required=True)
value = SerializerMethodField()
def get_value(self, obj: CustomFieldInstance):
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:
model = CustomFieldInstance
fields = [
"parent",
"field",
"value",
]
@ -463,7 +454,25 @@ class DocumentSerializer(OwnedObjectSerializer, DynamicFieldsModelSerializer):
doc["content"] = doc.get("content")[0:550]
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):
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:
new_datetime = datetime.datetime.combine(
validated_data.get("created_date"),