1
1
from __future__ import absolute_import
2
2
3
+ from django .test .client import RequestFactory
3
4
from django .utils import timezone
4
5
from rest_framework import serializers
6
+ from rest_framework .fields import SkipField
7
+ from rest_framework .reverse import reverse
5
8
6
9
from rest_framework_json_api .exceptions import Conflict
7
- from rest_framework_json_api .relations import ResourceRelatedField
10
+ from rest_framework_json_api .relations import (
11
+ HyperLinkedRelatedField ,
12
+ ResourceRelatedField ,
13
+ SerializerMethodHyperLinkedRelatedField
14
+ )
8
15
from rest_framework_json_api .utils import format_resource_type
9
16
10
17
from . import TestBase
11
18
from example .models import Author , Blog , Comment , Entry
12
19
from example .serializers import CommentSerializer
20
+ from example .views import EntryViewSet
13
21
14
22
15
23
class TestResourceRelatedField (TestBase ):
@@ -129,6 +137,117 @@ def test_invalid_resource_id_object(self):
129
137
}
130
138
131
139
140
+ class TestHyperLinkedFieldBase (TestBase ):
141
+
142
+ def setUp (self ):
143
+ super (TestHyperLinkedFieldBase , self ).setUp ()
144
+ self .blog = Blog .objects .create (name = 'Some Blog' , tagline = "It's a blog" )
145
+ self .entry = Entry .objects .create (
146
+ blog = self .blog ,
147
+ headline = 'headline' ,
148
+ body_text = 'body_text' ,
149
+ pub_date = timezone .now (),
150
+ mod_date = timezone .now (),
151
+ n_comments = 0 ,
152
+ n_pingbacks = 0 ,
153
+ rating = 3
154
+ )
155
+ self .comment = Comment .objects .create (
156
+ entry = self .entry ,
157
+ body = 'testing one two three' ,
158
+ )
159
+
160
+ self .request = RequestFactory ().get (reverse ('entry-detail' , kwargs = {'pk' : self .entry .pk }))
161
+ self .view = EntryViewSet (request = self .request , kwargs = {'entry_pk' : self .entry .id })
162
+
163
+
164
+ class TestHyperLinkedRelatedField (TestHyperLinkedFieldBase ):
165
+
166
+ def test_single_hyperlinked_related_field (self ):
167
+ field = HyperLinkedRelatedField (
168
+ related_link_view_name = 'entry-blog' ,
169
+ related_link_url_kwarg = 'entry_pk' ,
170
+ self_link_view_name = 'entry-relationships' ,
171
+ read_only = True ,
172
+ )
173
+ field ._context = {'request' : self .request , 'view' : self .view }
174
+ field .field_name = 'blog'
175
+
176
+ self .assertRaises (NotImplementedError , field .to_representation , self .entry )
177
+ self .assertRaises (SkipField , field .get_attribute , self .entry )
178
+
179
+ links_expected = {
180
+ 'self' : 'http://testserver/entries/{}/relationships/blog' .format (self .entry .pk ),
181
+ 'related' : 'http://testserver/entries/{}/blog' .format (self .entry .pk )
182
+ }
183
+ got = field .get_links (self .entry )
184
+ self .assertEqual (got , links_expected )
185
+
186
+ def test_many_hyperlinked_related_field (self ):
187
+ field = HyperLinkedRelatedField (
188
+ related_link_view_name = 'entry-comments' ,
189
+ related_link_url_kwarg = 'entry_pk' ,
190
+ self_link_view_name = 'entry-relationships' ,
191
+ read_only = True ,
192
+ many = True
193
+ )
194
+ field ._context = {'request' : self .request , 'view' : self .view }
195
+ field .field_name = 'comments'
196
+
197
+ self .assertRaises (NotImplementedError , field .to_representation , self .entry .comments .all ())
198
+ self .assertRaises (SkipField , field .get_attribute , self .entry )
199
+
200
+ links_expected = {
201
+ 'self' : 'http://testserver/entries/{}/relationships/comments' .format (self .entry .pk ),
202
+ 'related' : 'http://testserver/entries/{}/comments' .format (self .entry .pk )
203
+ }
204
+ got = field .child_relation .get_links (self .entry )
205
+ self .assertEqual (got , links_expected )
206
+
207
+
208
+ class TestSerializerMethodHyperLinkedRelatedField (TestHyperLinkedFieldBase ):
209
+
210
+ def test_single_serializer_method_hyperlinked_related_field (self ):
211
+ serializer = EntryModelSerializerWithHyperLinks (
212
+ instance = self .entry ,
213
+ context = {
214
+ 'request' : self .request ,
215
+ 'view' : self .view
216
+ }
217
+ )
218
+ field = serializer .fields ['blog' ]
219
+
220
+ self .assertRaises (NotImplementedError , field .to_representation , self .entry )
221
+ self .assertRaises (SkipField , field .get_attribute , self .entry )
222
+
223
+ expected = {
224
+ 'self' : 'http://testserver/entries/{}/relationships/blog' .format (self .entry .pk ),
225
+ 'related' : 'http://testserver/entries/{}/blog' .format (self .entry .pk )
226
+ }
227
+ got = field .get_links (self .entry )
228
+ self .assertEqual (got , expected )
229
+
230
+ def test_many_serializer_method_hyperlinked_related_field (self ):
231
+ serializer = EntryModelSerializerWithHyperLinks (
232
+ instance = self .entry ,
233
+ context = {
234
+ 'request' : self .request ,
235
+ 'view' : self .view
236
+ }
237
+ )
238
+ field = serializer .fields ['comments' ]
239
+
240
+ self .assertRaises (NotImplementedError , field .to_representation , self .entry )
241
+ self .assertRaises (SkipField , field .get_attribute , self .entry )
242
+
243
+ expected = {
244
+ 'self' : 'http://testserver/entries/{}/relationships/comments' .format (self .entry .pk ),
245
+ 'related' : 'http://testserver/entries/{}/comments' .format (self .entry .pk )
246
+ }
247
+ got = field .get_links (self .entry )
248
+ self .assertEqual (got , expected )
249
+
250
+
132
251
class BlogResourceRelatedField (ResourceRelatedField ):
133
252
def get_queryset (self ):
134
253
return Blog .objects
@@ -149,3 +268,32 @@ class EntryModelSerializer(serializers.ModelSerializer):
149
268
class Meta :
150
269
model = Entry
151
270
fields = ('authors' , 'comments' )
271
+
272
+
273
+ class EntryModelSerializerWithHyperLinks (serializers .ModelSerializer ):
274
+ blog = SerializerMethodHyperLinkedRelatedField (
275
+ related_link_view_name = 'entry-blog' ,
276
+ related_link_url_kwarg = 'entry_pk' ,
277
+ self_link_view_name = 'entry-relationships' ,
278
+ many = True ,
279
+ read_only = True ,
280
+ source = 'get_blog'
281
+ )
282
+ comments = SerializerMethodHyperLinkedRelatedField (
283
+ related_link_view_name = 'entry-comments' ,
284
+ related_link_url_kwarg = 'entry_pk' ,
285
+ self_link_view_name = 'entry-relationships' ,
286
+ many = True ,
287
+ read_only = True ,
288
+ source = 'get_comments'
289
+ )
290
+
291
+ class Meta :
292
+ model = Entry
293
+ fields = ('blog' , 'comments' ,)
294
+
295
+ def get_blog (self , obj ):
296
+ return obj .blog
297
+
298
+ def get_authors (self , obj ):
299
+ return obj .comments .all ()
0 commit comments