Ian Spivey avatar Ian Spivey committed fa05099

Allows handler.list to be canonical output definition.

Turns the breaking change from #157 into a configurable
setting.
Allows handler.list to be respected before Model fields
defined in typemapper, based on configuration.
Adds a settings variable, PISTON_EMITTER_PREFER_FIELDS.

Comments (0)

Files changed (2)

piston/emitters.py

                             'delete', 'model', 'anonymous',
                             'allowed_methods', 'fields', 'exclude' ])
 
-    def __init__(self, payload, typemapper, handler, fields=(), anonymous=True):
+    def __init__(self, payload, typemapper, handler, fields=(),
+                    anonymous=True, prefer_fields=False):
         self.typemapper = typemapper
         self.data = payload
         self.handler = handler
         self.fields = fields
         self.anonymous = anonymous
+        self.prefer_fields = prefer_fields
 
         if isinstance(self.data, Exception):
             raise
 
             if handler or fields:
                 v = lambda f: getattr(data, f.attname)
-                # FIXME
-                # Catch 22 here. Either we use the fields from the
-                # typemapped handler to make nested models work but the
-                # declared list_fields will ignored for models, or we
-                # use the list_fields from the base handler and accept that
-                # the nested models won't appear properly
-                # Refs #157
-                if handler:
-                    fields = getattr(handler, 'fields')    
-                
-                if not fields or hasattr(handler, 'fields'):
+                # If prefer_fields is True, then defer to the fields
+                #  described in the handler when serializing.  This allows
+                #  fields to be the canonical description of return value.
+                # Else defer to any fields registered for the model in
+                #  the typemapper, which allows nested models (via 
+                #  relationships) to be serialized as registered.
+                if not self.prefer_fields and handler:
+                    fields = getattr(handler, 'fields')
+
+                if not fields or (not self.prefer_fields and
+                    hasattr(handler, 'fields')):
                     """
                     Fields was not specified, try to find teh correct
                     version in the typemapper we were sent.

piston/resource.py

                                      False)
         self.default_emitter = getattr(settings, 'PISTON_DEFAULT_EMITTER',
                                        'json')
+        self.emitter_prefer_fields = getattr(settings,
+                'PISTON_EMITTER_PREFER_FIELDS', False)
 
     def determine_emitter(self, request, *args, **kwargs):
         """
             # the raw data
             result = result._container
 
-        srl = emitter(result, typemapper, handler, fields, anonymous)
+        srl = emitter(result, typemapper, handler, fields, anonymous,
+            self.emitter_prefer_fields)
 
         try:
             """
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.