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.