4
4
# SPDX-License-Identifier: GPL-2.0-or-later
5
5
6
6
from rest_framework .generics import ListAPIView
7
- from rest_framework .generics import RetrieveAPIView
8
- from rest_framework .serializers import (
9
- SerializerMethodField ,
10
- HyperlinkedRelatedField ,
11
- )
7
+ from rest_framework .generics import RetrieveUpdateAPIView
8
+ from rest_framework .serializers import SerializerMethodField
9
+ from rest_framework .serializers import HyperlinkedRelatedField
10
+ from rest_framework .serializers import ValidationError
12
11
13
12
from patchwork .api .base import BaseHyperlinkedModelSerializer
14
13
from patchwork .api .base import PatchworkPermission
@@ -34,8 +33,9 @@ class SeriesSerializer(BaseHyperlinkedModelSerializer):
34
33
read_only = True , view_name = 'api-series-detail' , many = True
35
34
)
36
35
supersedes = HyperlinkedRelatedField (
37
- read_only = True ,
38
36
view_name = 'api-series-detail' ,
37
+ queryset = Series .objects .all (),
38
+ required = False ,
39
39
many = True ,
40
40
)
41
41
superseded = HyperlinkedRelatedField (
@@ -44,6 +44,32 @@ class SeriesSerializer(BaseHyperlinkedModelSerializer):
44
44
many = True ,
45
45
)
46
46
47
+ def update (self , instance , validated_data , * args , ** kwargs ):
48
+ allowed_fields = {'supersedes' }
49
+ incoming_fields = set (validated_data .keys ())
50
+
51
+ if not incoming_fields .issubset (allowed_fields ):
52
+ invalid_fields = incoming_fields - allowed_fields
53
+ raise ValidationError (
54
+ {
55
+ 'detail' : 'Cannot update fields: '
56
+ f"{ ', ' .join (invalid_fields )} . Only 'supersedes' can be "
57
+ 'updated.'
58
+ }
59
+ )
60
+
61
+ if 'supersedes' in validated_data :
62
+ supersedes = validated_data .pop ('supersedes' , [])
63
+
64
+ try :
65
+ instance .supersedes .set (supersedes )
66
+ except Series .DoesNotExist :
67
+ raise ValidationError (
68
+ {'detail' : 'Unable to find one of the referenced series' }
69
+ )
70
+
71
+ return instance
72
+
47
73
def get_web_url (self , instance ):
48
74
request = self .context .get ('request' )
49
75
return request .build_absolute_uri (instance .get_absolute_url ())
@@ -100,7 +126,6 @@ class Meta:
100
126
'patches' ,
101
127
'dependencies' ,
102
128
'dependents' ,
103
- 'supersedes' ,
104
129
'superseded' ,
105
130
)
106
131
versioned_fields = {
@@ -140,7 +165,40 @@ class SeriesList(SeriesMixin, ListAPIView):
140
165
ordering = 'id'
141
166
142
167
143
- class SeriesDetail (SeriesMixin , RetrieveAPIView ):
144
- """Show a series."""
168
+ class SeriesDetail (SeriesMixin , RetrieveUpdateAPIView ):
169
+ """Show a series.
170
+
171
+ retrieve:
172
+ Return the details of a series.
173
+
174
+ update:
175
+ Only updates the 'supersedes' field of a series. Replaces the whole set
176
+ of superseded series.
177
+
178
+ ::
179
+
180
+ Instance:
181
+ instance.supersedes = [
182
+ 'http://example.com/api/series/1/',
183
+ 'http://example.com/api/series/2/',
184
+ 'http://example.com/api/series/5/'
185
+ ]
186
+
187
+ Request:
188
+ PUT/PATCH {
189
+ "supersedes": [
190
+ 'http://example.com/api/series/1/',
191
+ 'http://example.com/api/series/8/'
192
+ ]
193
+ }
194
+
195
+ Result:
196
+ instance.supersedes = [
197
+ 'http://example.com/api/series/1/',
198
+ 'http://example.com/api/series/8/'
199
+ ]
200
+ """
145
201
146
- pass
202
+ # PUT operation will behave as a partial update
203
+ def put (self , request , * args , ** kwargs ):
204
+ return self .partial_update (request , * args , ** kwargs )
0 commit comments