mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
180 lines
6.4 KiB
Python
180 lines
6.4 KiB
Python
''' Serializers for conceptual schema API. '''
|
|
import json
|
|
from typing import Optional
|
|
from rest_framework import serializers
|
|
|
|
import pyconcept
|
|
from .models import Constituenta, RSForm
|
|
|
|
|
|
class FileSerializer(serializers.Serializer):
|
|
''' Serializer: File input. '''
|
|
file = serializers.FileField(allow_empty_file=False)
|
|
|
|
def create(self, validated_data):
|
|
raise NotImplementedError('unexpected `create()` call')
|
|
|
|
def update(self, instance, validated_data):
|
|
raise NotImplementedError('unexpected `update()` call')
|
|
|
|
|
|
class ExpressionSerializer(serializers.Serializer):
|
|
''' Serializer: RSLang expression. '''
|
|
expression = serializers.CharField()
|
|
|
|
def create(self, validated_data):
|
|
raise NotImplementedError('unexpected `create()` call')
|
|
|
|
def update(self, instance, validated_data):
|
|
raise NotImplementedError('unexpected `update()` call')
|
|
|
|
|
|
class RSFormSerializer(serializers.ModelSerializer):
|
|
''' Serializer: General purpose RSForm data. '''
|
|
class Meta:
|
|
''' serializer metadata. '''
|
|
model = RSForm
|
|
fields = '__all__'
|
|
read_only_fields = ('owner', 'id')
|
|
|
|
|
|
class RSFormUploadSerializer(serializers.Serializer):
|
|
''' Upload data for RSForm serializer. '''
|
|
file = serializers.FileField()
|
|
load_metadata = serializers.BooleanField()
|
|
|
|
def create(self, validated_data):
|
|
raise NotImplementedError('unexpected `create()` call')
|
|
|
|
def update(self, instance, validated_data):
|
|
raise NotImplementedError('unexpected `update()` call')
|
|
|
|
|
|
class RSFormContentsSerializer(serializers.ModelSerializer):
|
|
''' Serializer: Detailed data for RSForm. '''
|
|
class Meta:
|
|
''' serializer metadata. '''
|
|
model = RSForm
|
|
|
|
def to_representation(self, instance: RSForm):
|
|
result = RSFormSerializer(instance).data
|
|
result['items'] = []
|
|
for cst in instance.constituents().order_by('order'):
|
|
result['items'].append(ConstituentaSerializer(cst).data)
|
|
return result
|
|
|
|
|
|
class RSFormDetailsSerlializer(serializers.BaseSerializer):
|
|
''' Serializer: Processed data for RSForm. '''
|
|
class Meta:
|
|
''' serializer metadata. '''
|
|
model = RSForm
|
|
|
|
def to_representation(self, instance: RSForm):
|
|
trs = pyconcept.check_schema(json.dumps(instance.to_trs()))
|
|
trs = trs.replace('entityUID', 'id')
|
|
result = json.loads(trs)
|
|
result['id'] = instance.pk
|
|
result['time_update'] = instance.time_update
|
|
result['time_create'] = instance.time_create
|
|
result['is_common'] = instance.is_common
|
|
result['owner'] = (instance.owner.pk if instance.owner is not None else None)
|
|
return result
|
|
|
|
def create(self, validated_data):
|
|
raise NotImplementedError('unexpected `create()` call')
|
|
|
|
def update(self, instance, validated_data):
|
|
raise NotImplementedError('unexpected `update()` call')
|
|
|
|
|
|
class ConstituentaSerializer(serializers.ModelSerializer):
|
|
''' Serializer: Constituenta data. '''
|
|
class Meta:
|
|
''' serializer metadata. '''
|
|
model = Constituenta
|
|
fields = '__all__'
|
|
read_only_fields = ('id', 'order', 'alias', 'cst_type', 'definition_resolved', 'term_resolved')
|
|
|
|
def update(self, instance: Constituenta, validated_data) -> Constituenta:
|
|
schema: RSForm = instance.schema
|
|
definition: Optional[str] = validated_data['definition_raw'] if 'definition_raw' in validated_data else None
|
|
term: Optional[str] = validated_data['term_raw'] if 'term_raw' in validated_data else None
|
|
term_changed = False
|
|
if definition is not None and definition != instance.definition_raw :
|
|
validated_data['definition_resolved'] = schema.resolver().resolve(definition)
|
|
if term is not None and term != instance.term_raw:
|
|
validated_data['term_resolved'] = schema.resolver().resolve(term)
|
|
if validated_data['term_resolved'] != instance.term_resolved:
|
|
validated_data['term_forms'] = []
|
|
term_changed = validated_data['term_resolved'] != instance.term_resolved
|
|
result: Constituenta = super().update(instance, validated_data)
|
|
if term_changed:
|
|
schema.on_term_change(result.alias)
|
|
result.refresh_from_db()
|
|
schema.save()
|
|
return result
|
|
|
|
|
|
class StandaloneCstSerializer(serializers.ModelSerializer):
|
|
''' Serializer: Constituenta in current context. '''
|
|
id = serializers.IntegerField()
|
|
|
|
class Meta:
|
|
''' serializer metadata. '''
|
|
model = Constituenta
|
|
exclude = ('schema', )
|
|
|
|
def validate(self, attrs):
|
|
try:
|
|
attrs['object'] = Constituenta.objects.get(pk=attrs['id'])
|
|
except Constituenta.DoesNotExist as exception:
|
|
raise serializers.ValidationError({f"{attrs['id']}": 'Конституента не существует'}) from exception
|
|
return attrs
|
|
|
|
|
|
class CstCreateSerializer(serializers.ModelSerializer):
|
|
''' Serializer: Constituenta creation. '''
|
|
insert_after = serializers.IntegerField(required=False, allow_null=True)
|
|
|
|
class Meta:
|
|
''' serializer metadata. '''
|
|
model = Constituenta
|
|
fields = 'alias', 'cst_type', 'convention', 'term_raw', 'definition_raw', 'definition_formal', 'insert_after'
|
|
|
|
|
|
class CstListSerlializer(serializers.Serializer):
|
|
''' Serializer: List of constituents from one origin. '''
|
|
items = serializers.ListField(
|
|
child=StandaloneCstSerializer()
|
|
)
|
|
|
|
def validate(self, attrs):
|
|
schema = self.context['schema']
|
|
cstList = []
|
|
for item in attrs['items']:
|
|
cst = item['object']
|
|
if cst.schema != schema:
|
|
raise serializers.ValidationError(
|
|
{'items': f'Конституенты должны относиться к данной схеме: {item}'})
|
|
cstList.append(cst)
|
|
attrs['constituents'] = cstList
|
|
return attrs
|
|
|
|
def create(self, validated_data):
|
|
raise NotImplementedError('unexpected `create()` call')
|
|
|
|
def update(self, instance, validated_data):
|
|
raise NotImplementedError('unexpected `update()` call')
|
|
|
|
|
|
class CstMoveSerlializer(CstListSerlializer):
|
|
''' Serializer: Change constituenta position. '''
|
|
move_to = serializers.IntegerField()
|
|
|
|
def create(self, validated_data):
|
|
raise NotImplementedError('unexpected `create()` call')
|
|
|
|
def update(self, instance, validated_data):
|
|
raise NotImplementedError('unexpected `update()` call')
|