Skip to content
This repository has been archived by the owner on Aug 11, 2021. It is now read-only.

Commit

Permalink
implement the Forking this Concept and mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
hao555sky committed Jun 23, 2017
1 parent 2cc136d commit fb517d6
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 7 deletions.
1 change: 1 addition & 0 deletions django-nonrel/ocl/collection/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ def propagate_owner_status(sender, instance=None, created=False, **kwargs):
class CollectionReferenceUtils():
@classmethod
def get_all_related_mappings(cls, expressions, collection):

all_related_mappings = []
unversioned_mappings = concept_expressions = []

Expand Down
5 changes: 5 additions & 0 deletions django-nonrel/ocl/collection/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class CollectionReferencesView(CollectionBaseView,
serializer_class = CollectionDetailSerializer

def initialize(self, request, path_info_segment, **kwargs):

if request.method in ['GET', 'HEAD']:
self.permission_classes = (CanViewConceptDictionary,)
else:
Expand All @@ -112,6 +113,7 @@ def get_level(self):
return 1

def update(self, request, *args, **kwargs):

if not self.parent_resource:
return HttpResponse(status=status.HTTP_405_METHOD_NOT_ALLOWED)

Expand Down Expand Up @@ -162,6 +164,7 @@ def create_success_message(self, added_references, expression):
message = self.select_update_message(expression)

references = filter(lambda reference: reference.startswith(expression), added_references)

if len(references) < 1:
return

Expand Down Expand Up @@ -211,6 +214,7 @@ def destroy(self, request, *args, **kwargs):
return Response({'message': 'ok!'}, status=status.HTTP_200_OK)

def get_related_mappings_with_version_information(self, cascade_mappings_flag, references):

related_mappings = []

for reference in references:
Expand Down Expand Up @@ -248,6 +252,7 @@ def select_update_message(self, expression):
return self.adding_to_head_message_by_type(resource_type)

resource_name = expression_parts[6]

return self.version_added_message_by_type(resource_name, self.parent_resource.name, resource_type)

def adding_to_head_message_by_type(self, resource_type):
Expand Down
10 changes: 10 additions & 0 deletions django-nonrel/ocl/concepts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ class Concept(ConceptValidationMixin, SubResourceBaseModel, DictionaryItemMixin)
descriptions = ListField(EmbeddedModelField(LocalizedText), null=True, blank=True)
retired = models.BooleanField(default=False)

version = models.TextField(null=True, blank=True)
forked_from_url = models.TextField(null=True, blank=True)
forked_concept_version = models.TextField(null=True, blank=True)

objects = MongoDBManager()


Expand Down Expand Up @@ -226,6 +230,9 @@ class ConceptVersion(ConceptValidationMixin, ResourceVersionModel):
version_created_by = models.TextField()
update_comment = models.TextField(null=True, blank=True)

forked_from_url = models.TextField(null=True, blank=True)
forked_concept_version = models.TextField(null=True, blank=True)

objects = MongoDBManager()

def clone(self):
Expand Down Expand Up @@ -376,6 +383,8 @@ def for_concept(cls, concept, label, previous_version=None, parent_version=None)
version_created_by=concept.created_by,
created_by=concept.created_by,
updated_by=concept.updated_by,
forked_from_url=concept.forked_from_url,
forked_concept_version=concept.forked_concept_version
)

@classmethod
Expand Down Expand Up @@ -519,3 +528,4 @@ def propagate_parent_attributes(sender, instance=None, created=False, **kwargs):
concept_version.public_access = instance.public_access
concept_version.save()
concept.save()

65 changes: 64 additions & 1 deletion django-nonrel/ocl/concepts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,16 @@ class ConceptDetailSerializer(serializers.Serializer):
created_on = serializers.DateTimeField(source='created_at', read_only=True)
updated_on = serializers.DateTimeField(source='updated_at', read_only=True)
extras = serializers.WritableField(required=False)
version = serializers.CharField(required=False)
forked_concept_version = serializers.CharField(required=False)
forked_from_url = serializers.CharField(required=False)

class Meta:
model = Concept
lookup_field = 'mnemonic'

def restore_object(self, attrs, instance=None):
print 'ConceptDetailSerializer attrs: ', attrs
concept = instance if instance else Concept()
concept.mnemonic = attrs.get(self.Meta.lookup_field, concept.mnemonic)
concept.external_id = attrs.get('external_id', concept.external_id)
Expand All @@ -58,13 +62,17 @@ def restore_object(self, attrs, instance=None):
concept.extras = attrs.get('extras', concept.extras)
concept.retired = attrs.get('retired', concept.retired)

concept.forked_from_url = attrs.get('forked_from_url', concept.forked_from_url)
concept.forked_concept_version = attrs.get('version', concept.version)

# Is this desired behavior??
concept.names = attrs.get('names', concept.names)

# Is this desired behavior??
concept.descriptions = attrs.get('descriptions', concept.descriptions)

concept.extras = attrs.get('extras', concept.extras)

return concept

def save_object(self, obj, **kwargs):
Expand All @@ -73,6 +81,58 @@ def save_object(self, obj, **kwargs):
self._errors.update(errors)


# class ConceptForkDetailSerializer(ResourceVersionSerializer):
# id = serializers.CharField(required=True, validators=[RegexValidator(regex=NAMESPACE_REGEX)], source='mnemonic')
# external_id = serializers.CharField(required=False)
# concept_class = serializers.CharField(required=False)
# datatype = serializers.CharField(required=False)
# display_name = serializers.CharField(read_only=True)
# display_locale = serializers.CharField(read_only=True)
# names = LocalizedTextListField(required=False)
# descriptions = LocalizedTextListField(required=False, name_override='description')
# retired = serializers.BooleanField(required=False)
# url = serializers.URLField(read_only=True)
# source = serializers.CharField(source='parent_resource', read_only=True)
# owner = serializers.CharField(source='owner_name', read_only=True)
# owner_type = serializers.CharField(read_only=True)
# owner_url = serializers.URLField(read_only=True)
# created_on = serializers.DateTimeField(source='created_at', read_only=True)
# updated_on = serializers.DateTimeField(source='updated_at', read_only=True)
# extras = serializers.WritableField(required=False)
# version = serializers.CharField(source='mnemonic')
# forked_concept_version = serializers.CharField(required=False)
# forked_from_url = serializers.CharField(required=False)
#
# class Meta:
# model = ConceptVersion
# lookup_field = 'mnemonic'
#
# def restore_object(self, attrs, instance=None):
# print 'ConceptForkDetailSerializer attrs: ', attrs
# concept = instance if instance else ConceptVersion()
# concept.mnemonic = attrs.get(self.Meta.lookup_field, concept.mnemonic)
# concept.external_id = attrs.get('external_id', concept.external_id)
# concept.concept_class = attrs.get('concept_class', concept.concept_class)
# concept.datatype = attrs.get('datatype', concept.datatype)
# concept.extras = attrs.get('extras', concept.extras)
# concept.retired = attrs.get('retired', concept.retired)
# concept.forked_concept_version = concept.mnemonic
# concept.forked_from_url = attrs.get('forked_from_url', concept.forked_from_url)
#
# # Is this desired behavior??
# concept.names = attrs.get('names', concept.names)
#
# # Is this desired behavior??
# concept.descriptions = attrs.get('descriptions', concept.descriptions)
#
# concept.extras = attrs.get('extras', concept.extras)
# return concept
#
# def save_object(self, obj, **kwargs):
# request_user = self.context['request'].user
# errors = Concept.persist_new(obj, request_user, **kwargs)
# self._errors.update(errors)


class ConceptVersionsSerializer(serializers.Serializer):
version = serializers.CharField(source='mnemonic')
Expand Down Expand Up @@ -102,6 +162,8 @@ class ConceptVersionListSerializer(ResourceVersionSerializer):
mappings = MappingListField(read_only=True)
is_latest_version = serializers.CharField()
locale = serializers.SerializerMethodField(method_name='get_locale')
forked_concept_version = serializers.CharField()
forked_from_url = serializers.CharField()

class Meta:
model = ConceptVersion
Expand All @@ -122,7 +184,6 @@ def __init__(self, *args, **kwargs):
mappings_field.source = 'get_empty_mappings'



class ConceptVersionDetailSerializer(ResourceVersionSerializer):
type = serializers.CharField(source='versioned_resource_type')
uuid = serializers.CharField(source='id')
Expand Down Expand Up @@ -150,6 +211,8 @@ class ConceptVersionDetailSerializer(ResourceVersionSerializer):
mappings = MappingListField(read_only=True)
is_latest_version = serializers.CharField()
locale = serializers.SerializerMethodField(method_name='get_locale')
forked_from_url = serializers.CharField()
forked_concept_version = serializers.CharField()

class Meta:
model = ConceptVersion
Expand Down
42 changes: 41 additions & 1 deletion django-nonrel/ocl/concepts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
DestroyAPIView, RetrieveUpdateDestroyAPIView, CreateAPIView,
ListCreateAPIView, ListAPIView)
from rest_framework.response import Response

from collection.models import Collection, CollectionVersion, CollectionReference, CollectionReferenceUtils

from concepts.filters import LimitSourceVersionFilter, PublicConceptsSearchFilter, LimitCollectionVersionFilter
from concepts.models import Concept, ConceptVersion, LocalizedText
from concepts.permissions import CanViewParentDictionary, CanEditParentDictionary
Expand Down Expand Up @@ -109,7 +112,7 @@ class ConceptVersionListAllView(BaseAPIView, ConceptVersionCSVFormatterMixin, Li
model = ConceptVersion
permission_classes = (CanViewParentDictionary,)
filter_backends = [PublicConceptsSearchFilter]
queryset = ConceptVersion.objects.filter(is_active=True)

solr_fields = {
'name': {'sortable': True, 'filterable': False},
'lastUpdate': {'sortable': True, 'filterable': False},
Expand Down Expand Up @@ -192,6 +195,43 @@ def create(self, request, *args, **kwargs):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ConceptForkView(ConceptBaseView,
mixins.CreateModelMixin):

@csrf_exempt
def dispatch(self, request, *args, **kwargs):
if request.method != 'POST':
delegate_view = ConceptVersionListView.as_view()
return delegate_view(request, *args, **kwargs)
return super(ConceptForkView, self).dispatch(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
self.permission_classes = (CanEditParentDictionary,)
self.serializer_class = ConceptDetailSerializer
return self.create(request, *args, **kwargs)

def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.DATA, files=request.FILES)

if serializer.is_valid():
self.pre_save(serializer.object)
save_kwargs = {
'force_insert': True,
'parent_resource': self.parent_resource,
'child_list_attribute': self.child_list_attribute
}
self.object = serializer.save(**save_kwargs)
if serializer.is_valid():
self.post_save(self.object, created=True)
headers = self.get_success_headers(serializer.data)
latest_version = ConceptVersion.get_latest_version_of(self.object)
serializer = ConceptVersionDetailSerializer(latest_version)
return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers)

return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class ConceptVersionsView(ConceptDictionaryMixin, ListWithHeadersMixin):
serializer_class = ConceptVersionListSerializer
permission_classes = (CanViewParentDictionary,)
Expand Down
6 changes: 5 additions & 1 deletion django-nonrel/ocl/mappings/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Mapping(MappingValidationMixin, BaseModel):
to_concept_name = models.TextField(null=True, blank=True)
retired = models.BooleanField(default=False)
external_id = models.TextField(null=True, blank=True)
is_internal_or_external = models.TextField()

class Meta:
unique_together = (
Expand All @@ -43,6 +44,7 @@ def clone(self, user):
to_concept_name=self.to_concept_name,
retired=self.retired,
external_id=self.external_id,
is_internal_or_external = self.is_internal_or_external,
)

@property
Expand Down Expand Up @@ -355,6 +357,7 @@ class MappingVersion(MappingValidationMixin, ResourceVersionModel):
external_id = models.TextField(null=True, blank=True)
is_latest_version = models.BooleanField(default=True)
update_comment = models.TextField(null=True, blank=True)
is_internal_or_external = models.TextField()

def clone(self):
return MappingVersion(
Expand All @@ -373,7 +376,8 @@ def clone(self):
previous_version=self,
parent_version=self.parent_version,
is_latest_version=self.is_latest_version,
extras=self.extras
extras=self.extras,
is_internal_or_external = self.is_internal_or_external
)

class Meta:
Expand Down
8 changes: 8 additions & 0 deletions django-nonrel/ocl/mappings/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def restore_object(self, attrs, instance=None):
mapping.to_concept_name = attrs.get('to_concept_name', mapping.to_concept_name)
mapping.to_concept_code = attrs.get('to_concept_code', mapping.to_concept_code)
mapping.external_id = attrs.get('external_id', mapping.external_id)
mapping.is_internal_or_external = attrs.get('is_internal_or_external',
mapping.is_internal_or_external)
return mapping

class Meta:
Expand All @@ -45,6 +47,8 @@ def restore_object(self, attrs, instance=None):
mapping_version.to_concept_name = attrs.get('to_concept_name', mapping_version.to_concept_name)
mapping_version.to_concept_code = attrs.get('to_concept_code', mapping_version.to_concept_code)
mapping_version.external_id = attrs.get('external_id', mapping_version.external_id)
mapping_version.is_internal_or_external = attrs.get('is_internal_or_external',
mapping_version.is_internal_or_external)
return mapping_version

class Meta:
Expand All @@ -57,6 +61,7 @@ class MappingDetailSerializer(MappingBaseSerializer):
external_id = serializers.CharField(required=False)
retired = serializers.BooleanField(required=False)
map_type = serializers.CharField(required=True)
is_internal_or_external = serializers.CharField(required=True)

from_source_owner = serializers.CharField(read_only=True)
from_source_owner_type = serializers.CharField(read_only=True)
Expand Down Expand Up @@ -95,6 +100,7 @@ class MappingVersionDetailSerializer(MappingVersionBaseSerializer):
external_id = serializers.CharField(required=False)
retired = serializers.BooleanField(required=False)
map_type = serializers.CharField(required=True)
is_internal_or_external = serializers.CharField(required=True)

from_source_owner = serializers.CharField(read_only=True)
from_source_owner_type = serializers.CharField(read_only=True)
Expand Down Expand Up @@ -139,6 +145,7 @@ class MappingListSerializer(MappingBaseSerializer):
to_concept_code = serializers.CharField(source='get_to_concept_code')
to_concept_name = serializers.CharField(source='get_to_concept_name')
url = serializers.CharField(read_only=True)
is_internal_or_external = serializers.CharField(required=True)


class MappingVersionListSerializer(ResourceVersionSerializer):
Expand Down Expand Up @@ -194,6 +201,7 @@ class MappingCreateSerializer(MappingBaseSerializer):
to_concept_code = serializers.CharField(required=False)
to_concept_name = serializers.CharField(required=False)
external_id = serializers.CharField(required=False)
is_internal_or_external = serializers.CharField(required=True)

def save_object(self, obj, **kwargs):
request_user = self.context['request'].user
Expand Down
5 changes: 4 additions & 1 deletion django-nonrel/ocl/oclapi/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ def get_head_of(cls, versioned_object):
LOOKUP_CONCEPT_CLASSES = ['Concept Class', 'Datatype', 'NameType', 'DescriptionType', 'MapType', 'Locale']
LOOKUP_SOURCES = ['Classes', 'Datatypes', 'NameTypes', 'DescriptionTypes', 'MapTypes', 'Locales']


class ConceptContainerModel(SubResourceBaseModel):
name = models.TextField()
full_name = models.TextField(null=True, blank=True)
Expand All @@ -230,6 +231,7 @@ class ConceptContainerModel(SubResourceBaseModel):
description = models.TextField(null=True, blank=True)
external_id = models.TextField(null=True, blank=True)
custom_validation_schema = models.TextField(blank=True, null=True)
allow_forking = models.BooleanField(default=False)

class Meta(SubResourceBaseModel.Meta):
abstract = True
Expand Down Expand Up @@ -378,6 +380,7 @@ class ConceptContainerVersionModel(ResourceVersionModel):
website = models.TextField(null=True, blank=True)
description = models.TextField(null=True, blank=True)
external_id = models.TextField(null=True, blank=True)
allow_forking = models.BooleanField(default=False)

class Meta(ResourceVersionModel.Meta):
abstract = True
Expand Down Expand Up @@ -516,4 +519,4 @@ def stamp_uri(sender, instance, **kwargs):
if hasattr(instance, 'versioned_object'):
instance.uri = reverse_resource_version(instance, instance.view_name)
else:
instance.uri = reverse_resource(instance, instance.view_name)
instance.uri = reverse_resource(instance, instance.view_name)
4 changes: 4 additions & 0 deletions django-nonrel/ocl/oclapi/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ def get_queryset(self):
queryset = super(ResourceVersionMixin, self).get_queryset()
versioned_object_type = ContentType.objects.get_for_model(self.versioned_object)
queryset = queryset.filter(versioned_object_type__pk=versioned_object_type.id, versioned_object_id=self.versioned_object.id)

print 'ResourceVersionMixin versioned_object_type: ', versioned_object_type
print 'ResourceVersionMixin queryset: ', queryset

return queryset


Expand Down
Loading

0 comments on commit fb517d6

Please sign in to comment.