11import json
2- import random
32import operator
3+ import random
44from functools import reduce
55
66
@@ -310,7 +310,9 @@ def random(self, count=None):
310310 if collection_count == 0 :
311311 return None
312312 elif count and count > collection_count :
313- raise ValueError ("count argument must be inferior to collection length." )
313+ raise ValueError (
314+ "count argument must be inferior to collection length."
315+ )
314316 elif count :
315317 self ._items = random .sample (self ._items , k = count )
316318 return self
@@ -330,15 +332,38 @@ def reverse(self):
330332 self ._items = self [::- 1 ]
331333
332334 def serialize (self , * args , ** kwargs ):
335+ """Serialize the collection into a list of dictionaries.
336+
337+ Returns:
338+ list: Returns a list of dictionaries.
339+ """
340+
333341 def _serialize (item ):
334- if self .__appends__ :
335- item .set_appends (self .__appends__ )
342+ if not hasattr (item , "serialize" ):
343+ return item
344+
345+ # Check if this item has already been serialized
346+ if not hasattr (self , "_serialized_objects" ):
347+ self ._serialized_objects = set ()
348+
349+ if id (item ) in self ._serialized_objects :
350+ # Return just the primary key if it's a circular reference
351+ return (
352+ item .get_primary_key_value ()
353+ if hasattr (item , "get_primary_key_value" )
354+ else None
355+ )
356+
357+ # Add this item to the set of serialized objects
358+ self ._serialized_objects .add (id (item ))
359+
360+ # Serialize the item
361+ result = item .serialize (* args , ** kwargs )
362+
363+ # Remove this item from the set of serialized objects
364+ self ._serialized_objects .remove (id (item ))
336365
337- if hasattr (item , "serialize" ):
338- return item .serialize (* args , ** kwargs )
339- elif hasattr (item , "to_dict" ):
340- return item .to_dict ()
341- return item
366+ return result
342367
343368 return list (map (_serialize , self ))
344369
@@ -424,17 +449,17 @@ def where(self, key, *args):
424449 if isinstance (item , dict ):
425450 comparison = item .get (key )
426451 else :
427- comparison = getattr (item , key ) if hasattr (item , key ) else False
452+ comparison = (
453+ getattr (item , key ) if hasattr (item , key ) else False
454+ )
428455 if self ._make_comparison (comparison , value , op ):
429456 attributes .append (item )
430457 return self .__class__ (attributes )
431458
432459 def where_in (self , key , args : list ) -> "Collection" :
433460 # Compatibility patch - allow numeric strings to match integers
434461 # (if all args are numeric strings)
435- if all (
436- [isinstance (arg , str ) and arg .isnumeric () for arg in args ]
437- ):
462+ if all ([isinstance (arg , str ) and arg .isnumeric () for arg in args ]):
438463 return self .where_in (key , [int (arg ) for arg in args ])
439464
440465 attributes = []
@@ -457,9 +482,7 @@ def where_in(self, key, args: list) -> "Collection":
457482 def where_not_in (self , key , args : list ) -> "Collection" :
458483 # Compatibility patch - allow numeric strings to match integers
459484 # (if all args are numeric strings)
460- if all (
461- [isinstance (arg , str ) and arg .isnumeric () for arg in args ]
462- ):
485+ if all ([isinstance (arg , str ) and arg .isnumeric () for arg in args ]):
463486 return self .where_not_in (key , [int (arg ) for arg in args ])
464487
465488 attributes = []
@@ -482,7 +505,9 @@ def where_not_in(self, key, args: list) -> "Collection":
482505 def zip (self , items ):
483506 items = self .__get_items (items )
484507 if not isinstance (items , list ):
485- raise ValueError ("The 'items' parameter must be a list or a Collection" )
508+ raise ValueError (
509+ "The 'items' parameter must be a list or a Collection"
510+ )
486511
487512 _items = []
488513 for x , y in zip (self , items ):
0 commit comments