I'm having issues serializing a 3rd party package (django-organizations) as I want to receive the context in JSON.
The class itself looks like this:
class OrganizationUserMixin(OrganizationMixin, JSONResponseMixin):
"""Mixin used like a SingleObjectMixin to fetch an organization user"""
user_model = OrganizationUser
org_user_context_name = 'organization_user'
def get_user_model(self):
return self.user_model
def get_context_data(self, **kwargs):
kwargs = super(OrganizationUserMixin, self).get_context_data(**kwargs)
kwargs.update({self.org_user_context_name: self.object,
self.org_context_name: self.object.organization})
return kwargs
def get_object(self):
""" Returns the OrganizationUser object based on the primary keys for both
the organization and the organization user.
"""
if hasattr(self, 'organization_user'):
return self.organization_user
organization_pk = self.kwargs.get('organization_pk', None)
user_pk = self.kwargs.get('user_pk', None)
self.organization_user = get_object_or_404(
self.get_user_model().objects.select_related(),
user__pk=user_pk, organization__pk=organization_pk)
return self.organization_user
And I'm trying to pass this custom JSONResponseMixin to my OrganizationUserMixin
class:
class JSONResponseMixin:
"""
A mixin that can be used to render a JSON response.
"""
def render_to_json_response(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
return JsonResponse(
self.get_data(context),
**response_kwargs
)
def get_data(self, context):
print(context)
return context
And then overriding the render_to_response
in OrganizationUserMixin
as such:
def render_to_response(self, context, **response_kwargs):
return self.render_to_json_response(context, **response_kwargs)
If I print context
It looks something like this
# {
# 'object': <OrganizationUser: Erik (MyOrgName)>,
# 'organizationuser': <OrganizationUser: Erik (MyOrgName)>,
# 'organization': <Organization: MyOrgName>,
# 'view': <organizations.views.OrganizationUserDetail object at 0x1091a3ac0>,
# 'organization_user': <OrganizationUser: Erik (MyOrgName)>
# }
The error message I get is TypeError: Object of type OrganizationUser is not JSON serializable
How can I serialize the context
in my JSONResponseMixin?
You have two options here, either use Django rest framework (DRF) or implement functions that performs serialization for the models.
Option 1
DRF is a more sustainable solution as you grow the API side of your application, as it would abstract most of de/serialization work, and provide you with alot of other useful functionalities, such as Routers, ViewSets, and other.
Example Code
# serializers.py
from rest_framework import serializers
class OrganizationUserSerializer(serializers.ModelSerializer):
class Meta:
model = OrganizationUser
fields = '__all__'
# views.py
from rest_framework import generics
class OrganizationUser(generics.RetrieveModelMixin):
queryset = OrganizationUser.objects.all()
serializer_class = OrganizationUserSerializer
Option 2
That being said, if you the JsonResponseMixin
is sufficient for most of your needs, and your application is not mainly reliant on the API, you can get away with just adding serialization functions for your models and calling them in your JsonResponseMixin.get_data()
Example code:
# Models.py
class OrganizationUser(models.Model):
...
def to_json(self):
# assuming you have a field name and organization
return {"name": self.name, "organization": self.organization.to_json()}
# mixins.py
class JSONResponseMixin:
"""
A mixin that can be used to render a JSON response.
"""
def render_to_json_response(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
return JsonResponse(
self.get_data(context),
**response_kwargs
)
def get_data(self, context):
data = {}
for key, val in context:
if hasattr(val, "to_json"):
data[key] = val.to_json()
else:
data[key] = val
return data