Saving some more work on this, even though it will fail linting

This commit is contained in:
Trenton Holmes 2023-11-02 08:26:17 -07:00 committed by shamoon
parent 3787f4f8fe
commit 63d6213272
5 changed files with 140 additions and 62 deletions

View File

@ -16,6 +16,7 @@ django-extensions = "*"
django-filter = "~=23.3" django-filter = "~=23.3"
djangorestframework = "~=3.14" djangorestframework = "~=3.14"
djangorestframework-guardian = "*" djangorestframework-guardian = "*"
drf-writable-nested = "*"
filelock = "*" filelock = "*"
gunicorn = "*" gunicorn = "*"
imap-tools = "*" imap-tools = "*"

10
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "7b4272de2042a346f3252ae20e7bbeee60c375381f59526caa35511a706d4977" "sha256": "3c380d590439f008ec85f1d5821ed96b4ebd56fcee3f287e6e0a6f5923262229"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": {}, "requires": {},
@ -522,6 +522,14 @@
"index": "pypi", "index": "pypi",
"version": "==0.3.0" "version": "==0.3.0"
}, },
"drf-writable-nested": {
"hashes": [
"sha256:154c0381e8a3a477e0fd539d5e1caf8ff4c1097a9c0c0fe741d4858b11b0455b"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==0.7.0"
},
"exceptiongroup": { "exceptiongroup": {
"hashes": [ "hashes": [
"sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9", "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9",

View File

@ -1008,15 +1008,6 @@ class CustomFieldInstance(models.Model):
return CustomFieldInteger return CustomFieldInteger
raise NotImplementedError(self.field.data_type) raise NotImplementedError(self.field.data_type)
def to_json(self) -> dict[str, str]:
return {
"id": self.id,
"created": self.created,
"type": self.field.data_type,
"name": self.field.name,
"data": self.value,
}
@staticmethod @staticmethod
def from_json( def from_json(
document: Document, document: Document,

View File

@ -396,6 +396,9 @@ class StoragePathField(serializers.PrimaryKeyRelatedField):
return StoragePath.objects.all() return StoragePath.objects.all()
from drf_writable_nested.serializers import NestedUpdateMixin
class CustomFieldSerializer(serializers.ModelSerializer): class CustomFieldSerializer(serializers.ModelSerializer):
data_type = serializers.ChoiceField( data_type = serializers.ChoiceField(
choices=CustomField.FieldDataType, choices=CustomField.FieldDataType,
@ -411,21 +414,54 @@ class CustomFieldSerializer(serializers.ModelSerializer):
] ]
class CustomFieldInstanceSerializer(serializers.Serializer): class CustomFieldOnUpdateSerializer(serializers.ModelSerializer):
field = CustomFieldSerializer(required=True) id = serializers.PrimaryKeyRelatedField(queryset=CustomField.objects.all())
value = SerializerMethodField()
class Meta:
model = CustomField
fields = [
"id",
]
class CustomFieldInstanceSerializer(serializers.ModelSerializer):
field = serializers.PrimaryKeyRelatedField(queryset=CustomField.objects.all())
value = serializers.JSONField()
def create(self, validated_data):
print("hello from create")
from pprint import pprint
pprint(dict(validated_data))
document: Document = validated_data["document"]
custom_field: CustomField = validated_data["field"]
instance, _ = CustomFieldInstance.objects.get_or_create(
document=document, field=custom_field
)
instance_data_class = instance.field_type
_, _ = instance_data_class.objects.update_or_create(
parent=instance, defaults={"value": validated_data["value"]}
)
return instance
def update(self, instance: CustomFieldInstance, validated_data):
print("hello from update")
from pprint import pprint
pprint(validated_data)
pprint(instance.id)
def get_value(self, obj: CustomFieldInstance): def get_value(self, obj: CustomFieldInstance):
return obj.value return obj.value
class Meta: class Meta:
fields = [ model = CustomFieldInstance
"field", fields = ["value", "field"]
"value",
]
class DocumentSerializer(OwnedObjectSerializer, DynamicFieldsModelSerializer): class DocumentSerializer(
OwnedObjectSerializer, NestedUpdateMixin, DynamicFieldsModelSerializer
):
correspondent = CorrespondentField(allow_null=True) correspondent = CorrespondentField(allow_null=True)
tags = TagsField(many=True) tags = TagsField(many=True)
document_type = DocumentTypeField(allow_null=True) document_type = DocumentTypeField(allow_null=True)
@ -459,29 +495,6 @@ class DocumentSerializer(OwnedObjectSerializer, DynamicFieldsModelSerializer):
return doc return doc
def update(self, instance: Document, validated_data): def update(self, instance: Document, validated_data):
if "custom_fields" in validated_data:
custom_fields = validated_data.pop("custom_fields")
for index, field_data in enumerate(custom_fields):
# get field value from initial_data since its not on the model
initial_field_data = self.initial_data["custom_fields"][index]
CustomFieldInstance.from_json(
document=instance,
field=initial_field_data["field"],
value=initial_field_data["value"],
)
existing_fields = CustomFieldInstance.objects.filter(document=instance)
for existing_field in existing_fields:
if (
not len(
[
f
for f in self.initial_data["custom_fields"]
if f["field"]["id"] == existing_field.field.id
],
)
> 0
):
existing_field.delete()
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"),

View File

@ -2,9 +2,10 @@ from django.contrib.auth.models import User
from rest_framework import status from rest_framework import status
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
from documents.models import CustomField from documents.models import CustomField, CustomFieldInstance, CustomFieldShortText
from documents.models import Document from documents.models import Document
from documents.tests.utils import DirectoriesMixin from documents.tests.utils import DirectoriesMixin
from pprint import pprint
class TestCustomField(DirectoriesMixin, APITestCase): class TestCustomField(DirectoriesMixin, APITestCase):
@ -80,41 +81,105 @@ class TestCustomField(DirectoriesMixin, APITestCase):
data={ data={
"custom_fields": [ "custom_fields": [
{ {
"field": { "field": custom_field_string.id,
"id": custom_field_string.id,
},
"value": "test value", "value": "test value",
}, },
{ {
"field": { "field": custom_field_date.id,
"id": custom_field_date.id,
},
"value": "2023-10-31", "value": "2023-10-31",
}, },
{ {
"field": { "field": custom_field_int.id,
"id": custom_field_int.id, "value": "3",
},
"value": 3,
}, },
{ {
"field": { "field": custom_field_boolean.id,
"id": custom_field_boolean.id, "value": "True",
},
"value": True,
}, },
{ {
"field": { "field": custom_field_url.id,
"id": custom_field_url.id,
},
"value": "https://example.com", "value": "https://example.com",
}, },
], ],
}, },
format="json", format="json",
) )
from pprint import pprint
print("Response data")
pprint(resp.json())
self.assertEqual(resp.status_code, status.HTTP_200_OK)
resp_data = resp.json()["custom_fields"]
self.assertCountEqual(
resp_data,
[
{"field": custom_field_string.id, "value": "test value"},
{"field": custom_field_date.id, "value": "2023-10-31"},
{"field": custom_field_int.id, "value": 3},
{"field": custom_field_boolean.id, "value": True},
{"field": custom_field_url.id, "value": "https://example.com"},
],
)
doc.refresh_from_db()
self.assertEqual(len(doc.custom_fields.all()), 5)
for custom_field in doc.custom_fields.all():
print(custom_field.value, type(custom_field.value))
def test_change_custom_field_instance_value(self):
doc = Document.objects.create(
title="WOW",
content="the content",
checksum="123",
mime_type="application/pdf",
)
custom_field_string = CustomField.objects.create(
name="Test Custom Field String",
data_type=CustomField.FieldDataType.STRING,
)
self.assertEqual(CustomFieldInstance.objects.count(), 0)
self.assertEqual(CustomFieldShortText.objects.count(), 0)
resp = self.client.patch(
f"/api/documents/{doc.id}/",
data={
"custom_fields": [
{
"field": custom_field_string.id,
"value": "test value",
},
],
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
pprint(resp.json())
self.assertEqual(doc.custom_fields.first().value, "test value")
self.assertEqual(CustomFieldInstance.objects.count(), 1)
self.assertEqual(CustomFieldShortText.objects.count(), 1)
resp = self.client.patch(
f"/api/documents/{doc.id}/",
data={
"custom_fields": [
{
"field": custom_field_string.id,
"value": "a new test value",
},
],
},
format="json",
)
self.assertEqual(resp.status_code, status.HTTP_200_OK) self.assertEqual(resp.status_code, status.HTTP_200_OK)
doc.refresh_from_db() pprint(resp.json())
self.assertEqual(len(doc.custom_fields.all()), 5)
self.assertEqual(doc.custom_fields.first().value, "test value") self.assertEqual(doc.custom_fields.first().value, "a new test value")
self.assertEqual(CustomFieldInstance.objects.count(), 1)
self.assertEqual(CustomFieldShortText.objects.count(), 1)