Skip to content

Instantly share code, notes, and snippets.

@siteshen
Created November 4, 2013 04:10
Show Gist options
  • Select an option

  • Save siteshen/7297960 to your computer and use it in GitHub Desktop.

Select an option

Save siteshen/7297960 to your computer and use it in GitHub Desktop.
A ready to use Django JSONResponseMixin and an instance/JSON convertor.
from .models import Profile
from .django_json_mixin import JSONListView, JSONDetailView
class AccountList(JSONListView):
model = Profile
class AccountDetail(JSONDetailView):
model = Profile
def get_object(self):
user = self.request.user
return user.profile
import json
from django.http import HttpResponse
from django.views.generic.detail import BaseDetailView
from django.views.generic.list import BaseListView
from . import django_json_utils as utils
class JSONResponseMixin(object):
columns = None
date_format = '%Y-%m-%d'
time_format = '%H:%M:%S'
datetime_format = None
"""
A mixin that can be used to render a JSON response.
"""
response_class = HttpResponse
def render_to_response(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
response_kwargs['content_type'] = 'application/json'
return self.response_class(
self.convert_context_to_json(context),
**response_kwargs
)
def convert_context_to_json(self, context):
"Convert the context dictionary into a JSON object."
raise NotImplementedError()
def convert_object_to_json(self, object):
"Convert the an object into a JSON object"
return utils.to_json_dict(object,
columns=self.columns,
date_format=self.date_format,
time_format=self.time_format,
datetime_format=self.datetime_format)
class JSONListView(JSONResponseMixin, BaseListView):
allow_empty = True
def convert_context_to_json(self, context):
page = 1
if context.get('page_obj'):
page = context['page_obj'].number
result = {
'page': page,
'list': [],
}
result['list'] = [self.convert_object_to_json(object)
for object in context['object_list']]
return json.dumps(result)
class JSONDetailView(JSONResponseMixin, BaseDetailView):
def convert_context_to_json(self, context):
result = self.convert_object_to_json(context['object'])
return json.dumps(result)
import datetime
import decimal
import json
from django.db import models
def get_field_names(obj):
"""Get NORMAL field name list."""
def _is_security(field_name):
return not (field_name in ['password'] or
field_name.endswith('_ptr'))
return [field.name for field in obj._meta.fields
if _is_security(field.name)]
def to_json_dict(obj, columns=None,
date_format='%Y-%m-%d',
time_format='%H:%M:%S',
datetime_format=None):
"""Convert Django Model instance to JSON object.
Inverse function of from_json_dict.
"""
result = {}
columns = columns or get_field_names(obj)
datetime_format = datetime_format or ' '.join([date_format, time_format])
for key in columns:
val = getattr(obj, key)
if isinstance(val, models.Model):
result[key] = to_json_dict(
val, date_format=date_format, time_format=time_format,
datetime_format=datetime_format)
elif isinstance(val, datetime.datetime):
result[key] = val.strftime(datetime_format)
elif isinstance(val, datetime.date):
result[key] = val.strftime(date_format)
elif isinstance(val, datetime.time):
result[key] = val.strftime(time_format)
elif isinstance(val, decimal.Decimal):
result[key] = str(val)
else:
result[key] = val
return result
def to_json_str(obj, *args, **kwargs):
"""Convert Django Model instance to JSON string.
Inverse function of from_json_str.
"""
json_dict = to_json_dict(obj, *args, **kwargs)
return json.dumps(json_dict)
def from_json_dict(model_cls, json_dict,
date_format='%Y-%m-%d',
time_format='%H:%M:%S',
datetime_format=None):
"""Convert JSON object to Django Model instance.
Inverse function of to_json_dict.
"""
raise NotImplementedError()
def from_json_str(model_cls, json_str, *args, **kwargs):
"""Convert JSON string to Django Model instance.
Inverse function of to_json_str.
"""
json_dict = json.loads(json_str)
return from_json_dict(model_cls, json_dict, *args, **kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment