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

Commit 013a366

Browse files
committed
implement the Forking this Concept and mapping
1 parent 8986e79 commit 013a366

File tree

11 files changed

+150
-5
lines changed

11 files changed

+150
-5
lines changed

django-nonrel/ocl/collection/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ def propagate_owner_status(sender, instance=None, created=False, **kwargs):
425425
class CollectionReferenceUtils():
426426
@classmethod
427427
def get_all_related_mappings(cls, expressions, collection):
428+
428429
all_related_mappings = []
429430
unversioned_mappings = concept_expressions = []
430431

django-nonrel/ocl/collection/views.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ class CollectionReferencesView(CollectionBaseView,
102102
serializer_class = CollectionDetailSerializer
103103

104104
def initialize(self, request, path_info_segment, **kwargs):
105+
105106
if request.method in ['GET', 'HEAD']:
106107
self.permission_classes = (CanViewConceptDictionary,)
107108
else:
@@ -112,6 +113,7 @@ def get_level(self):
112113
return 1
113114

114115
def update(self, request, *args, **kwargs):
116+
115117
if not self.parent_resource:
116118
return HttpResponse(status=status.HTTP_405_METHOD_NOT_ALLOWED)
117119

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

164166
references = filter(lambda reference: reference.startswith(expression), added_references)
167+
165168
if len(references) < 1:
166169
return
167170

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

213216
def get_related_mappings_with_version_information(self, cascade_mappings_flag, references):
217+
214218
related_mappings = []
215219

216220
for reference in references:
@@ -248,6 +252,7 @@ def select_update_message(self, expression):
248252
return self.adding_to_head_message_by_type(resource_type)
249253

250254
resource_name = expression_parts[6]
255+
251256
return self.version_added_message_by_type(resource_name, self.parent_resource.name, resource_type)
252257

253258
def adding_to_head_message_by_type(self, resource_type):

django-nonrel/ocl/concepts/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ class Concept(ConceptValidationMixin, SubResourceBaseModel, DictionaryItemMixin)
5858
descriptions = ListField(EmbeddedModelField(LocalizedText), null=True, blank=True)
5959
retired = models.BooleanField(default=False)
6060

61+
version = models.TextField(null=True, blank=True)
62+
forked_from_url = models.TextField(null=True, blank=True)
63+
forked_concept_version = models.TextField(null=True, blank=True)
64+
6165
objects = MongoDBManager()
6266

6367

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

233+
forked_from_url = models.TextField(null=True, blank=True)
234+
forked_concept_version = models.TextField(null=True, blank=True)
235+
229236
objects = MongoDBManager()
230237

231238
def clone(self):
@@ -376,6 +383,8 @@ def for_concept(cls, concept, label, previous_version=None, parent_version=None)
376383
version_created_by=concept.created_by,
377384
created_by=concept.created_by,
378385
updated_by=concept.updated_by,
386+
forked_from_url=concept.forked_from_url,
387+
forked_concept_version=concept.forked_concept_version
379388
)
380389

381390
@classmethod
@@ -519,3 +528,4 @@ def propagate_parent_attributes(sender, instance=None, created=False, **kwargs):
519528
concept_version.public_access = instance.public_access
520529
concept_version.save()
521530
concept.save()
531+

django-nonrel/ocl/concepts/serializers.py

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,16 @@ class ConceptDetailSerializer(serializers.Serializer):
4444
created_on = serializers.DateTimeField(source='created_at', read_only=True)
4545
updated_on = serializers.DateTimeField(source='updated_at', read_only=True)
4646
extras = serializers.WritableField(required=False)
47+
version = serializers.CharField(required=False)
48+
forked_concept_version = serializers.CharField(required=False)
49+
forked_from_url = serializers.CharField(required=False)
4750

4851
class Meta:
4952
model = Concept
5053
lookup_field = 'mnemonic'
5154

5255
def restore_object(self, attrs, instance=None):
56+
print 'ConceptDetailSerializer attrs: ', attrs
5357
concept = instance if instance else Concept()
5458
concept.mnemonic = attrs.get(self.Meta.lookup_field, concept.mnemonic)
5559
concept.external_id = attrs.get('external_id', concept.external_id)
@@ -58,13 +62,17 @@ def restore_object(self, attrs, instance=None):
5862
concept.extras = attrs.get('extras', concept.extras)
5963
concept.retired = attrs.get('retired', concept.retired)
6064

65+
concept.forked_from_url = attrs.get('forked_from_url', concept.forked_from_url)
66+
concept.forked_concept_version = attrs.get('version', concept.version)
67+
6168
# Is this desired behavior??
6269
concept.names = attrs.get('names', concept.names)
6370

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

6774
concept.extras = attrs.get('extras', concept.extras)
75+
6876
return concept
6977

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

7583

84+
# class ConceptForkDetailSerializer(ResourceVersionSerializer):
85+
# id = serializers.CharField(required=True, validators=[RegexValidator(regex=NAMESPACE_REGEX)], source='mnemonic')
86+
# external_id = serializers.CharField(required=False)
87+
# concept_class = serializers.CharField(required=False)
88+
# datatype = serializers.CharField(required=False)
89+
# display_name = serializers.CharField(read_only=True)
90+
# display_locale = serializers.CharField(read_only=True)
91+
# names = LocalizedTextListField(required=False)
92+
# descriptions = LocalizedTextListField(required=False, name_override='description')
93+
# retired = serializers.BooleanField(required=False)
94+
# url = serializers.URLField(read_only=True)
95+
# source = serializers.CharField(source='parent_resource', read_only=True)
96+
# owner = serializers.CharField(source='owner_name', read_only=True)
97+
# owner_type = serializers.CharField(read_only=True)
98+
# owner_url = serializers.URLField(read_only=True)
99+
# created_on = serializers.DateTimeField(source='created_at', read_only=True)
100+
# updated_on = serializers.DateTimeField(source='updated_at', read_only=True)
101+
# extras = serializers.WritableField(required=False)
102+
# version = serializers.CharField(source='mnemonic')
103+
# forked_concept_version = serializers.CharField(required=False)
104+
# forked_from_url = serializers.CharField(required=False)
105+
#
106+
# class Meta:
107+
# model = ConceptVersion
108+
# lookup_field = 'mnemonic'
109+
#
110+
# def restore_object(self, attrs, instance=None):
111+
# print 'ConceptForkDetailSerializer attrs: ', attrs
112+
# concept = instance if instance else ConceptVersion()
113+
# concept.mnemonic = attrs.get(self.Meta.lookup_field, concept.mnemonic)
114+
# concept.external_id = attrs.get('external_id', concept.external_id)
115+
# concept.concept_class = attrs.get('concept_class', concept.concept_class)
116+
# concept.datatype = attrs.get('datatype', concept.datatype)
117+
# concept.extras = attrs.get('extras', concept.extras)
118+
# concept.retired = attrs.get('retired', concept.retired)
119+
# concept.forked_concept_version = concept.mnemonic
120+
# concept.forked_from_url = attrs.get('forked_from_url', concept.forked_from_url)
121+
#
122+
# # Is this desired behavior??
123+
# concept.names = attrs.get('names', concept.names)
124+
#
125+
# # Is this desired behavior??
126+
# concept.descriptions = attrs.get('descriptions', concept.descriptions)
127+
#
128+
# concept.extras = attrs.get('extras', concept.extras)
129+
# return concept
130+
#
131+
# def save_object(self, obj, **kwargs):
132+
# request_user = self.context['request'].user
133+
# errors = Concept.persist_new(obj, request_user, **kwargs)
134+
# self._errors.update(errors)
135+
76136

77137
class ConceptVersionsSerializer(serializers.Serializer):
78138
version = serializers.CharField(source='mnemonic')
@@ -102,6 +162,8 @@ class ConceptVersionListSerializer(ResourceVersionSerializer):
102162
mappings = MappingListField(read_only=True)
103163
is_latest_version = serializers.CharField()
104164
locale = serializers.SerializerMethodField(method_name='get_locale')
165+
forked_concept_version = serializers.CharField()
166+
forked_from_url = serializers.CharField()
105167

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

124186

125-
126187
class ConceptVersionDetailSerializer(ResourceVersionSerializer):
127188
type = serializers.CharField(source='versioned_resource_type')
128189
uuid = serializers.CharField(source='id')
@@ -150,6 +211,8 @@ class ConceptVersionDetailSerializer(ResourceVersionSerializer):
150211
mappings = MappingListField(read_only=True)
151212
is_latest_version = serializers.CharField()
152213
locale = serializers.SerializerMethodField(method_name='get_locale')
214+
forked_from_url = serializers.CharField()
215+
forked_concept_version = serializers.CharField()
153216

154217
class Meta:
155218
model = ConceptVersion

django-nonrel/ocl/concepts/views.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
DestroyAPIView, RetrieveUpdateDestroyAPIView, CreateAPIView,
99
ListCreateAPIView, ListAPIView)
1010
from rest_framework.response import Response
11+
12+
from collection.models import Collection, CollectionVersion, CollectionReference, CollectionReferenceUtils
13+
1114
from concepts.filters import LimitSourceVersionFilter, PublicConceptsSearchFilter, LimitCollectionVersionFilter
1215
from concepts.models import Concept, ConceptVersion, LocalizedText
1316
from concepts.permissions import CanViewParentDictionary, CanEditParentDictionary
@@ -109,7 +112,7 @@ class ConceptVersionListAllView(BaseAPIView, ConceptVersionCSVFormatterMixin, Li
109112
model = ConceptVersion
110113
permission_classes = (CanViewParentDictionary,)
111114
filter_backends = [PublicConceptsSearchFilter]
112-
queryset = ConceptVersion.objects.filter(is_active=True)
115+
113116
solr_fields = {
114117
'name': {'sortable': True, 'filterable': False},
115118
'lastUpdate': {'sortable': True, 'filterable': False},
@@ -192,6 +195,43 @@ def create(self, request, *args, **kwargs):
192195
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
193196

194197

198+
class ConceptForkView(ConceptBaseView,
199+
mixins.CreateModelMixin):
200+
201+
@csrf_exempt
202+
def dispatch(self, request, *args, **kwargs):
203+
if request.method != 'POST':
204+
delegate_view = ConceptVersionListView.as_view()
205+
return delegate_view(request, *args, **kwargs)
206+
return super(ConceptForkView, self).dispatch(request, *args, **kwargs)
207+
208+
def post(self, request, *args, **kwargs):
209+
self.permission_classes = (CanEditParentDictionary,)
210+
self.serializer_class = ConceptDetailSerializer
211+
return self.create(request, *args, **kwargs)
212+
213+
def create(self, request, *args, **kwargs):
214+
serializer = self.get_serializer(data=request.DATA, files=request.FILES)
215+
216+
if serializer.is_valid():
217+
self.pre_save(serializer.object)
218+
save_kwargs = {
219+
'force_insert': True,
220+
'parent_resource': self.parent_resource,
221+
'child_list_attribute': self.child_list_attribute
222+
}
223+
self.object = serializer.save(**save_kwargs)
224+
if serializer.is_valid():
225+
self.post_save(self.object, created=True)
226+
headers = self.get_success_headers(serializer.data)
227+
latest_version = ConceptVersion.get_latest_version_of(self.object)
228+
serializer = ConceptVersionDetailSerializer(latest_version)
229+
return Response(serializer.data, status=status.HTTP_201_CREATED,
230+
headers=headers)
231+
232+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
233+
234+
195235
class ConceptVersionsView(ConceptDictionaryMixin, ListWithHeadersMixin):
196236
serializer_class = ConceptVersionListSerializer
197237
permission_classes = (CanViewParentDictionary,)

django-nonrel/ocl/mappings/models.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class Mapping(MappingValidationMixin, BaseModel):
2323
to_concept_name = models.TextField(null=True, blank=True)
2424
retired = models.BooleanField(default=False)
2525
external_id = models.TextField(null=True, blank=True)
26+
is_internal_or_external = models.TextField()
2627

2728
class Meta:
2829
unique_together = (
@@ -43,6 +44,7 @@ def clone(self, user):
4344
to_concept_name=self.to_concept_name,
4445
retired=self.retired,
4546
external_id=self.external_id,
47+
is_internal_or_external = self.is_internal_or_external,
4648
)
4749

4850
@property
@@ -355,6 +357,7 @@ class MappingVersion(MappingValidationMixin, ResourceVersionModel):
355357
external_id = models.TextField(null=True, blank=True)
356358
is_latest_version = models.BooleanField(default=True)
357359
update_comment = models.TextField(null=True, blank=True)
360+
is_internal_or_external = models.TextField()
358361

359362
def clone(self):
360363
return MappingVersion(
@@ -373,7 +376,8 @@ def clone(self):
373376
previous_version=self,
374377
parent_version=self.parent_version,
375378
is_latest_version=self.is_latest_version,
376-
extras=self.extras
379+
extras=self.extras,
380+
is_internal_or_external = self.is_internal_or_external
377381
)
378382

379383
class Meta:

django-nonrel/ocl/mappings/serializers.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ def restore_object(self, attrs, instance=None):
2323
mapping.to_concept_name = attrs.get('to_concept_name', mapping.to_concept_name)
2424
mapping.to_concept_code = attrs.get('to_concept_code', mapping.to_concept_code)
2525
mapping.external_id = attrs.get('external_id', mapping.external_id)
26+
mapping.is_internal_or_external = attrs.get('is_internal_or_external',
27+
mapping.is_internal_or_external)
2628
return mapping
2729

2830
class Meta:
@@ -45,6 +47,8 @@ def restore_object(self, attrs, instance=None):
4547
mapping_version.to_concept_name = attrs.get('to_concept_name', mapping_version.to_concept_name)
4648
mapping_version.to_concept_code = attrs.get('to_concept_code', mapping_version.to_concept_code)
4749
mapping_version.external_id = attrs.get('external_id', mapping_version.external_id)
50+
mapping_version.is_internal_or_external = attrs.get('is_internal_or_external',
51+
mapping_version.is_internal_or_external)
4852
return mapping_version
4953

5054
class Meta:
@@ -57,6 +61,7 @@ class MappingDetailSerializer(MappingBaseSerializer):
5761
external_id = serializers.CharField(required=False)
5862
retired = serializers.BooleanField(required=False)
5963
map_type = serializers.CharField(required=True)
64+
is_internal_or_external = serializers.CharField(required=True)
6065

6166
from_source_owner = serializers.CharField(read_only=True)
6267
from_source_owner_type = serializers.CharField(read_only=True)
@@ -95,6 +100,7 @@ class MappingVersionDetailSerializer(MappingVersionBaseSerializer):
95100
external_id = serializers.CharField(required=False)
96101
retired = serializers.BooleanField(required=False)
97102
map_type = serializers.CharField(required=True)
103+
is_internal_or_external = serializers.CharField(required=True)
98104

99105
from_source_owner = serializers.CharField(read_only=True)
100106
from_source_owner_type = serializers.CharField(read_only=True)
@@ -139,6 +145,7 @@ class MappingListSerializer(MappingBaseSerializer):
139145
to_concept_code = serializers.CharField(source='get_to_concept_code')
140146
to_concept_name = serializers.CharField(source='get_to_concept_name')
141147
url = serializers.CharField(read_only=True)
148+
is_internal_or_external = serializers.CharField(required=True)
142149

143150

144151
class MappingVersionListSerializer(ResourceVersionSerializer):
@@ -194,6 +201,7 @@ class MappingCreateSerializer(MappingBaseSerializer):
194201
to_concept_code = serializers.CharField(required=False)
195202
to_concept_name = serializers.CharField(required=False)
196203
external_id = serializers.CharField(required=False)
204+
is_internal_or_external = serializers.CharField(required=True)
197205

198206
def save_object(self, obj, **kwargs):
199207
request_user = self.context['request'].user

django-nonrel/ocl/oclapi/views.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,10 @@ def get_queryset(self):
331331
queryset = super(ResourceVersionMixin, self).get_queryset()
332332
versioned_object_type = ContentType.objects.get_for_model(self.versioned_object)
333333
queryset = queryset.filter(versioned_object_type__pk=versioned_object_type.id, versioned_object_id=self.versioned_object.id)
334+
335+
print 'ResourceVersionMixin versioned_object_type: ', versioned_object_type
336+
print 'ResourceVersionMixin queryset: ', queryset
337+
334338
return queryset
335339

336340

django-nonrel/ocl/sources/urls.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
from django.conf.urls import patterns, url, include
2+
from concepts.views import ConceptForkView, ConceptCreateView
23
from sources.feeds import SourceFeed
3-
from sources.views import SourceListView, SourceRetrieveUpdateDestroyView, SourceVersionRetrieveUpdateView, SourceVersionChildListView, SourceVersionListView, SourceVersionRetrieveUpdateDestroyView, SourceExtrasView, SourceExtraRetrieveUpdateDestroyView, SourceVersionExportView
4+
from sources.views import SourceListView, SourceRetrieveUpdateDestroyView, SourceVersionRetrieveUpdateView, \
5+
SourceVersionChildListView, SourceVersionListView, SourceVersionRetrieveUpdateDestroyView, SourceExtrasView, \
6+
SourceExtraRetrieveUpdateDestroyView, SourceVersionExportView
47

58
__author__ = 'misternando'
69

710
urlpatterns = patterns('',
811
url(r'^$', SourceListView.as_view(), name='source-list'),
912
url(r'^(?P<source>[a-zA-Z0-9\-\.]+)/$', SourceRetrieveUpdateDestroyView.as_view(), name='source-detail'),
13+
url(r'^(?P<source>[a-zA-Z0-9\-\.]+)/forking/$', ConceptForkView.as_view(), name='concept-fork'),
1014
url(r'^(?P<source>[a-zA-Z0-9\-\.]+)/atom/$', SourceFeed()),
1115
url(r'^(?P<source>[a-zA-Z0-9\-\.]+)/versions/$', SourceVersionListView.as_view(), name='sourceversion-list'),
1216
url(r'^(?P<source>[a-zA-Z0-9\-\.]+)/latest/$', SourceVersionRetrieveUpdateView.as_view(), {'is_latest': True}, name='sourceversion-latest-detail'),

django-nonrel/ocl/tasks.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ def delete_resources_from_collection_in_solr(version_id, concepts, mappings):
118118

119119
@celery.task
120120
def add_references(SerializerClass, user, data, parent_resource, host_url, cascade_mappings=False):
121+
121122
expressions = data.get('expressions', [])
122123
concept_expressions = data.get('concepts', [])
123124
mapping_expressions = data.get('mappings', [])
@@ -178,6 +179,7 @@ def add_references(SerializerClass, user, data, parent_resource, host_url, casca
178179
diff = map(lambda ref: ref, CollectionReference.diff(serializer.object.references, prev_refs))
179180

180181
errors = serializer.errors.get('references', [])
182+
181183
return diff, errors
182184

183185

0 commit comments

Comments
 (0)