On Monday 05 June 2017 04:14:01 Alison P wrote:

> If I use the default session serializer, I get the following error:
> TypeError at /login/
> 
> <class 'OneTimePasswordBackend'> is not JSON serializable

I'm using this is a general solution. Feel free to strike what you don't need.
The basics is that a JSONEncoder knows primitives and how to recurse 
containers. The rest is 
passed to a method "default", which generates the above error message. 
Subclasses should 
override it to implement their own knowledge about objects to serialize.

*class JSONModelEncoder(*DjangoJSONEncoder*):    *exclude_callback *= None    
*recurse_foreign_keys *= True

    def get_excluded_fields(*self, instance*):        if *self.exclude_callback 
*is not None:            
return *self.exclude_callback*(*instance*)        else:            return *[]

    *def recurse_foreign(*self, instance, field*) *-> */dict/**:        *retval 
*= {}        if 
/isinstance/(*field, models.OneToOneField*):            */# OneToOneField is a 
subclass of 
ForeignKey, thus must be placed            # before ForeignKey.            # If 
parent_link is true, then 
we need to pull in the fields            # as if they were part of the current 
model.            /*if not 
*field.parent_link*:                *parent_obj *= /getattr/(*instance, 
field.name*)                if 
*parent_obj *is not None:                    *value *= *self.model_to_dict*(    
                    *parent_obj,                        
exclude*=*self.get_excluded_fields*(*parent_obj*)                    )          
          
*retval.update*(*value*)        elif /isinstance/(*field, models.ForeignKey*):  
          */# Resolve 
the model pointed to.            /foreign *= /getattr/(*instance, field.name*)  
          if *foreign *is 
not None:                *value *= *self.model_to_dict*(*foreign*)              
  *retval[field.name] *= 
*value            *else:                *retval[field.name] *= None        elif 
/isinstance/(*field, 
models.ManyToManyField*):            */# Create a list of model dicts.          
  /modlist *= *[]            
related *= /getattr/(*instance, field.name*)            for *rel *in *related*: 
               
*modlist.append*(*self.model_to_dict*(*rel*))

            *retval[field.name] *= *modlist        *else:            raise 
/TypeError/('recurse_foreign 
called on {}'*.format*(/type/(*field*)))

        return *retval

    *def link_foreign(*self, instance, field*) *-> */dict/**:        if 
/isinstance/(*field, 
models.ManyToManyField*):            return *self.recurse_foreign*(*instance, 
field*)        elif 
/isinstance/(*field, models.OneToOneField*):            if not 
*field.parent_link*:                return 
*self.recurse_foreign*(*instance, field*)        elif /isinstance/(*field, 
models.ForeignKey*):            
*foreign *= /getattr/(*instance, field.name*)            */# raise 
ValueError(repr(foreign))            /*if 
*foreign *is not None:                if /getattr/(*foreign, *'absolute_url'*, 
*False):                    return {                        
*field.name*: {                            'text': *force_text*(*foreign*)*,    
                        *'link': 
*foreign.absolute_url,                        *}                    }           
     else:                    return {                        
*field.name*: {                            'text': *force_text*(*foreign*)*,    
                        *'pk': 
*foreign.pk                        *}                    }

        return {}

    def model_to_dict(*self, instance, exclude*=None*, ****kwargs*) *-> 
*/dict/**:        
*"""Convert a model instance to a dictionary of field names and values.

        If the model has a method of the same name, that method is called for   
     three reasons:            
#. Centralization. This method can be used in other parts of django             
  or an application to 
provide a consistent dictionary of the               model.            #. The 
default implementation only 
maps fields. If the model has               important attributes that are 
implemented as properties 
this               mixin will not find them.            #. Hiding of sensitive 
fields. The model is better 
equipped to               evaluate if a field contains sensitive information.

         /:param/ instance: the model instance to convert         /:type/ 
instance: models.Model         
/:param/ exclude: list of fields to exclude from being sent         /:type/ 
exclude: list        """        
exclude *= *exclude *or *self.get_excluded_fields*(*instance*)        if 
/hasattr/(*instance, 
*'model_to_dict') and *\                */callable/**(/getattr/(*instance, 
*'model_to_dict')):            
return *instance.model_to_dict*(*exclude, ****kwargs*)        *retval *= {}     
   for *field *in 
*instance._meta.fields*:            if *field.name *in *exclude*:               
 continue            if 
/isinstance/(*field, *(*models.ForeignKey, models.ManyToManyField*)):           
     if 
*self.recurse_foreign_keys*:                    
*retval.update*(*self.recurse_foreign*(*instance, 
field*))                else:                    *merge *= 
*self.link_foreign*(*instance, field*)                    if 
*merge*:                        *retval.update*(*merge*)            else:       
         *retval[field.name] *= 
/getattr/(*instance, field.name*)

        return *retval

    *def default(*self, obj*) *-> */object/**:        *"""Prepares a value for 
json representation.

        Complex types that are not containers should be handled by this method. 
       /:param/ obj:        
/:type/ obj: object        """        *if /isinstance/(*obj, 
models.query.QuerySet*):            return 
/list/(*obj*)        elif /hasattr/(*obj, *'model_to_dict') and *\              
  */callable/**(/getattr/(*obj, 
*'model_to_dict')):            return 
*obj.model_to_dict*(*exclude*=*self.get_excluded_fields*(*obj*))        elif 
/isinstance/(*obj, 
models.Model*):            return *self.model_to_dict*(*obj*)        else:      
      return 
/super/()*.default*(*obj*)

*
-- 
Melvyn Sopacua

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/2490212.PBjjLfRLnk%40devstation.
For more options, visit https://groups.google.com/d/optout.

Reply via email to