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 django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
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