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