Skip to content

Commit f68fab7

Browse files
authored
Fix invalid values in RelationListFieldSerializer. (#1818)
* Fix invalid values in serializer. * Add test to check deleted relations * use to_id attribute to check content's existance.
1 parent 6e5e669 commit f68fab7

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

news/1818.bugfix

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix response of `RelationListFieldSerializer` by filtering out invalid items. @Faakhir30

src/plone/restapi/serializer/relationfield.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,16 @@ class RelationChoiceFieldSerializer(DefaultFieldSerializer):
3333
@adapter(IRelationList, IDexterityContent, Interface)
3434
@implementer(IFieldSerializer)
3535
class RelationListFieldSerializer(DefaultFieldSerializer):
36-
pass
36+
def get_value(self, default=[]):
37+
"""Return field value reduced to list of non-broken Relationvalues.
38+
39+
Args:
40+
default (list, optional): Default field value. Defaults to empty list.
41+
42+
Returns:
43+
list: List of RelationValues
44+
"""
45+
value = super().get_value()
46+
if not value:
47+
return []
48+
return [el for el in value if el.to_id]

src/plone/restapi/tests/test_dxcontent_serializer.py

+28
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
from zope.component import provideAdapter
2828
from zope.component import queryUtility
2929
from zope.interface import Interface
30+
from z3c.relationfield import RelationValue
31+
from z3c.relationfield.event import _setRelation
32+
from zope.component import getUtility
33+
from zope.intid.interfaces import IIntIds
3034
from zope.publisher.interfaces.browser import IBrowserRequest
3135
from importlib import import_module
3236

@@ -191,6 +195,30 @@ def test_serializer_includes_expansion(self):
191195
"foo",
192196
)
193197

198+
def test_serializer_excludes_deleted_relations(self):
199+
200+
intids = getUtility(IIntIds)
201+
self.portal.invokeFactory(
202+
"DXTestDocument",
203+
id="doc2",
204+
)
205+
rel1 = RelationValue(intids.getId(self.portal.doc1))
206+
rel2 = RelationValue(intids.getId(self.portal.doc2))
207+
self.portal.doc1.test_relationlist_field = [
208+
rel1,
209+
rel2,
210+
]
211+
_setRelation(self.portal.doc1, "test_relationlist_field", rel1)
212+
_setRelation(self.portal.doc1, "test_relationlist_field", rel2)
213+
# delete doc2 to make sure we have a None value in the relation list
214+
self.portal.manage_delObjects(["doc2"])
215+
216+
obj = self.serialize()
217+
self.assertEqual(1, len(obj["test_relationlist_field"]))
218+
self.assertEqual(
219+
"http://nohost/plone/doc1", obj["test_relationlist_field"][0]["@id"]
220+
)
221+
194222
def test_get_is_folderish(self):
195223
obj = self.serialize()
196224
self.assertIn("is_folderish", obj)

0 commit comments

Comments
 (0)