Skip to content
This repository was archived by the owner on Jun 1, 2022. It is now read-only.

Commit 18ac1af

Browse files
committed
Split topics into three: "project", "wn", and a "virtual" combination
Based on what we discussed in #291
1 parent f20e7ab commit 18ac1af

File tree

5 files changed

+132
-27
lines changed

5 files changed

+132
-27
lines changed

editorsnotes/api/ld.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
('itm', 'http://spi-fm.uca.es/spdef/models/genericTools/itm/1.0#'),
1111
('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'),
1212
('schema', 'http://schema.org/'),
13+
('vaem', 'http://www.linkedmodel.org/schema/vaem#'),
1314
('xsd', 'http://www.w3.org/2001/XMLSchema#'),
1415
('wn', ROOT_NAMESPACE),
1516
))
@@ -25,6 +26,11 @@
2526
('@id', '@graph'),
2627
('@container', '@index'),
2728
))),
29+
('aspects', 'vaem:hasAspect'),
30+
('data', OrderedDict((
31+
('@id', '@graph'),
32+
('@container', '@index'),
33+
))),
2834
('display_name', 'schema:name'),
2935
('embedded', OrderedDict((
3036
('@id', '@graph'),

editorsnotes/api/serializers/topics.py

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,69 @@
11
from rest_framework import serializers
2+
from rest_framework.reverse import reverse
23

34
from editorsnotes.main.models import Topic
45

56
from .. import fields
6-
from ..ld import ROOT_NAMESPACE
77
from ..validators import UniqueToProjectValidator
88

99
from .mixins import EmbeddedItemsMixin, RelatedTopicSerializerMixin
1010

1111

12-
__all__ = ['TopicSerializer']
12+
__all__ = ['TopicSerializer', 'ENTopicSerializer']
1313

1414

15-
class TopicSerializer(RelatedTopicSerializerMixin, EmbeddedItemsMixin,
16-
serializers.ModelSerializer):
15+
class TopicSerializer(EmbeddedItemsMixin, serializers.ModelSerializer):
1716
url = fields.IdentityURLField(view_name='api:topics-detail')
18-
type = serializers.SerializerMethodField()
17+
data = serializers.SerializerMethodField()
18+
aspects = serializers.SerializerMethodField()
1919
project = fields.HyperlinkedAffiliatedProjectField(
2020
default=fields.CurrentProjectDefault())
2121
updaters = fields.UpdatersField()
2222

23+
class Meta:
24+
model = Topic
25+
fields = (
26+
'url',
27+
'project',
28+
'updaters',
29+
'created',
30+
'last_updated',
31+
'aspects',
32+
'data',
33+
34+
)
35+
embedded_fields = (
36+
'project',
37+
'updaters',
38+
)
39+
40+
def get_aspects(self, obj):
41+
return [
42+
reverse('api:topics-wn-detail',
43+
args=[obj.project.slug, obj.pk],
44+
request=self.context['request']),
45+
reverse('api:topics-proj-detail',
46+
args=[obj.project.slug, obj.pk],
47+
request=self.context['request'])
48+
]
49+
50+
def get_data(self, obj):
51+
en_topic_url, project_topic_url = self.get_aspects(obj)
52+
return {
53+
en_topic_url: {
54+
"@id": en_topic_url,
55+
"@graph": ENTopicSerializer(obj, context=self.context).data
56+
},
57+
project_topic_url: {
58+
"@id": project_topic_url,
59+
"@graph": {}
60+
}
61+
}
62+
63+
64+
class ENTopicSerializer(RelatedTopicSerializerMixin, EmbeddedItemsMixin,
65+
serializers.ModelSerializer):
66+
url = fields.IdentityURLField(view_name='api:topics-detail')
2367
related_topics = fields.TopicAssignmentField(many=True)
2468

2569
references = fields.UnqualifiedURLField(
@@ -30,37 +74,21 @@ class TopicSerializer(RelatedTopicSerializerMixin, EmbeddedItemsMixin,
3074
class Meta:
3175
model = Topic
3276
fields = (
33-
'id',
3477
'url',
35-
'type',
36-
'project',
37-
3878
'preferred_name',
39-
40-
'created',
41-
'last_updated',
42-
'updaters',
43-
44-
'types',
45-
'same_as',
4679
'alternate_names',
4780

81+
'related_topics',
82+
4883
'markup',
4984
'markup_html',
5085

51-
'related_topics',
5286
'references',
5387
'referenced_by',
5488
)
5589
embedded_fields = (
56-
'project',
57-
'updaters',
58-
5990
'related_topics',
6091
'references',
6192
'referenced_by',
6293
)
6394
validators = [UniqueToProjectValidator('preferred_name')]
64-
65-
def get_type(self, obj):
66-
return ROOT_NAMESPACE + 'Topic'

editorsnotes/api/tests/serializers.py

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ def get_project_url(self, obj):
4848
)
4949

5050
data = json.loads(JSONRenderer().render(test_serializer.data))
51-
project_data = json.loads(JSONRenderer().render(project_serializer.data))
51+
project_data = json.loads(
52+
JSONRenderer().render(project_serializer.data))
5253

5354
self.assertEqual(data, {
5455
'project_url': project_url,
@@ -92,10 +93,66 @@ def test_document_serializer(self):
9293
)
9394

9495
self.assertEqual(
95-
self.dummy_request.build_absolute_uri(transcript.get_absolute_url()),
96+
self.dummy_request.build_absolute_uri(
97+
transcript.get_absolute_url()),
9698
transcript_url)
9799

98100
serializer = en_serializers.DocumentSerializer(
99101
instance=self.document, context=self.context,
100102
include_embeds=True)
101103
self.assertNotEqual(serializer.data['embedded'][transcript_url], None)
104+
105+
106+
class TopicSerializerTestCase(ClearContentTypesTransactionTestCase):
107+
fixtures = ['projects.json']
108+
109+
def setUp(self):
110+
self.dummy_request = RequestFactory().get('/')
111+
self.context = {'request': self.dummy_request}
112+
113+
self.project = Project.objects.get(slug='emma')
114+
self.user = self.project.members.get()
115+
116+
self.topic = main_models.Topic.objects.create(
117+
creator=self.user,
118+
last_updater=self.user,
119+
project=self.project,
120+
preferred_name='Emma Goldman'
121+
)
122+
123+
def test_topic_serializer(self):
124+
serializer = en_serializers.TopicSerializer(
125+
instance=self.topic,
126+
context=self.context,
127+
include_embeds=True
128+
)
129+
130+
base_url = self.dummy_request.build_absolute_uri(
131+
self.topic.get_absolute_url())
132+
wn_topic_url = base_url + 'w/'
133+
project_topic_url = base_url + 'p/'
134+
135+
self.assertEqual(serializer.data['url'], base_url)
136+
self.assertListEqual(serializer.data['aspects'], [
137+
wn_topic_url,
138+
project_topic_url
139+
])
140+
141+
self.assertDictEqual(serializer.data['data'][wn_topic_url], {
142+
"@id": wn_topic_url,
143+
"@graph": {
144+
"url": base_url,
145+
"preferred_name": "Emma Goldman",
146+
"alternate_names": [],
147+
"related_topics": [],
148+
"markup": None,
149+
"markup_html": None,
150+
"references": [],
151+
"referenced_by": []
152+
}
153+
})
154+
155+
self.assertDictEqual(serializer.data['data'][project_topic_url], {
156+
"@id": project_topic_url,
157+
"@graph": {}
158+
})

editorsnotes/api/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ def format_patterns(urlpatterns):
3535
### Topics ###
3636
url(r'^/topics/$', views.TopicList.as_view(), name='topics-list'),
3737
url(r'^/topics/(?P<pk>\d+)/$', views.TopicDetail.as_view(), name='topics-detail'),
38+
url(r'^/topics/(?P<pk>\d+)/w/$', views.ENTopicDetail.as_view(), name='topics-wn-detail'),
39+
url(r'^/topics/(?P<pk>\d+)/p/$', views.TopicDetail.as_view(), name='topics-proj-detail'),
3840
url(r'^/topics/(?P<pk>\d+)/confirm_delete$', views.TopicConfirmDelete.as_view(), name='topics-confirm-delete'),
3941

4042
### Notes ###

editorsnotes/api/views/topics.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
from editorsnotes.main.models import Topic
22

33
from .. import filters as es_filters
4-
from ..serializers.topics import TopicSerializer
4+
from ..serializers.topics import TopicSerializer, ENTopicSerializer
55

66
from .base import BaseListAPIView, BaseDetailView, DeleteConfirmAPIView
77
from .mixins import (ElasticSearchListMixin, EmbeddedReferencesMixin,
88
HydraAffordancesMixin)
99

10-
__all__ = ['TopicList', 'TopicDetail', 'TopicConfirmDelete']
10+
__all__ = [
11+
'TopicList',
12+
'TopicDetail',
13+
'ENTopicDetail',
14+
'TopicConfirmDelete'
15+
]
1116

1217

1318
class TopicList(ElasticSearchListMixin, BaseListAPIView):
@@ -28,6 +33,13 @@ class TopicDetail(EmbeddedReferencesMixin, HydraAffordancesMixin,
2833
hydra_project_perms = ('main.change_topic', 'main.delete_topic',)
2934

3035

36+
class ENTopicDetail(EmbeddedReferencesMixin, HydraAffordancesMixin,
37+
BaseDetailView):
38+
queryset = Topic.objects.all()
39+
serializer_class = ENTopicSerializer
40+
hydra_project_perms = ('main.change_topic', 'main.delete_topic',)
41+
42+
3143
class TopicConfirmDelete(DeleteConfirmAPIView):
3244
queryset = Topic.objects.all()
3345
permissions = {

0 commit comments

Comments
 (0)