44from  api_v2  import  models 
55
66
7- class  GameContentSerializer (serializers .HyperlinkedModelSerializer ):
7+ class  GameContentSerializer (serializers .HyperlinkedModelSerializer ):   
88
9-     def  remove_unwanted_fields (self , fields_to_keep ):
10-         fields_to_keep  =  set (fields_to_keep .split ("," ))
11-         all_fields  =  set (self .fields .keys ())
12-         for  field  in  all_fields  -  fields_to_keep :
13-             self .fields .pop (field , None )
14-     
9+     def  remove_unwanted_fields (self , dynamic_params ):
10+         """ 
11+         Takes the value of the 'fields', a string of comma-seperated values,  
12+         and removes all other fields from the serializer 
13+         """ 
14+         if  fields_to_keep  :=  dynamic_params .pop ("fields" , None ):
15+             fields_to_keep  =  set (fields_to_keep .split ("," ))
16+             all_fields  =  set (self .fields .keys ())
17+             for  field  in  all_fields  -  fields_to_keep :
18+                 self .fields .pop (field , None )
1519
16-     # Adding dynamic "fields" qs parameter. 
17-     def  __init__ (self , * args , ** kwargs ):
20+     def  get_or_create_dynamic_params (self , child ):
21+         """ 
22+         Creates dynamic params on the serializer context if it doesn't already 
23+         exist, then returns the dynamic parameters 
24+         """ 
25+         if  "dynamic_params"  not  in   self .fields [child ]._context :
26+             self .fields [child ]._context .update ({"dynamic_params" : {}})
27+         return  self .fields [child ]._context ["dynamic_params" ]
28+ 
29+     @staticmethod  
30+     def  split_param (dynamic_param ):
31+         crumbs  =  dynamic_param .split ("__" )
32+         return  crumbs [0 ], "__" .join (crumbs [1 :]) if  len (crumbs ) >  1  else  None 
33+ 
34+     def  set_dynamic_params_for_children (self , dynamic_params ):
35+         for  param , fields  in  dynamic_params .items ():
36+             child , child_dynamic_param  =  self .split_param (param )
37+             if  child  in  set (self .fields .keys ()):
38+                 dynamic_params  =  self .get_or_create_dynamic_params (child )
39+                 dynamic_params .update ({child_dynamic_param : fields })
40+ 
41+     @staticmethod  
42+     def  is_param_dynamic (p ):
43+         """ 
44+         Currently only the 'fields' query param is supported 
45+         """ 
46+         return  p .endswith ("fields" )
47+ 
48+     def  get_dynamic_params_for_root (self , request ):
49+         query_params  =  request .query_params .items ()
50+         return  {k : v  for  k , v  in  query_params  if  self .is_param_dynamic (k )}
1851
52+     def  get_dynamic_params (self ):
53+         """ 
54+         When dynamic params get passed down in set_context_for_children 
55+         If the child is a subclass of ListSerializer (has many=True) 
56+         The context must be fetched from ListSerializer Class 
57+         """ 
58+         if  isinstance (self .parent , serializers .ListSerializer ):
59+             return  self .parent ._context .get ("dynamic_params" , {})
60+         return  self ._context .get ("dynamic_params" , {})
61+ 
62+     def  __init__ (self , * args , ** kwargs ):
1963        request  =  kwargs .get ("context" , {}).get ("request" )
20-         # Instantiate the superclass normally 
21-         super (GameContentSerializer , self ).__init__ (* args , ** kwargs )
64+         super ().__init__ (* args , ** kwargs )
2265
23-         # request only exists  on root, not on nested queries  or when generating OAS file  
66+         # " request" doesn't exist  on the child serializers,  or when generating OAS spec  
2467        is_root  =  bool (request )
25- 
2668        if  is_root :
27-             fields  =  request .query_params .get ('fields' )
28-             if  fields :
29-                 self .remove_unwanted_fields (fields )
69+             if  request .method  !=  "GET" :
70+                 return 
3071
31-             depth  =  request .query_params .get ('depth' )
32-             if  depth :
72+             if  depth :=  request .query_params .get ('depth' ):
3373                try :
3474                    depth_value  =  int (depth )
3575                    if  depth_value  >  0  and  depth_value  <  3 :
@@ -44,5 +84,16 @@ def __init__(self, *args, **kwargs):
4484            else :
4585                self .Meta .depth  =  0  #The default. 
4686
87+             #  
88+             dynamic_params  =  self .get_dynamic_params_for_root (request )
89+             self ._context .update ({"dynamic_params" : dynamic_params })
90+     
91+     def  to_representation (self , * args , ** kwargs ):
92+         if  dynamic_params  :=  self .get_dynamic_params ().copy ():
93+             self .remove_unwanted_fields (dynamic_params )
94+             self .set_dynamic_params_for_children (dynamic_params )
95+ 
96+         return  super ().to_representation (* args , ** kwargs )
97+ 
4798    class  Meta :
48-         abstract  =  True 
99+         abstract  =  True 
0 commit comments