Created
July 1, 2017 13:56
-
-
Save Northshoot/360e50c9be9d9da9fba6582743eb20b3 to your computer and use it in GitHub Desktop.
This is a small class that i wrote that extends the functionality of the JsonSerializer from django.Why i wrote this??Two majors points: 1. I need to serialize @Property parameters for my grid builded using jQuery 2. To get the label of choices values and to serialize that values not the flags as the default django serialize do; - Exemplo [( "TI…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import warnings | |
from django.core.serializers.json import Serializer | |
from django.utils.encoding import smart_text, is_protected_type | |
from django.utils import six | |
from django.utils.html import escape | |
import json | |
class JsonPropertySerializer(Serializer): | |
def serialize(self, queryset, **options): | |
""" | |
Serialize a queryset. | |
""" | |
self.options = options | |
self.stream = options.pop("stream", six.StringIO()) | |
self.selected_fields = options.pop("fields", None) | |
self.use_natural_keys = options.pop("use_natural_keys", False) | |
if self.use_natural_keys: | |
warnings.warn("``use_natural_keys`` is deprecated; use ``use_natural_foreign_keys`` instead.", PendingDeprecationWarning) | |
self.use_natural_foreign_keys = options.pop('use_natural_foreign_keys', False) or self.use_natural_keys | |
self.use_natural_primary_keys = options.pop('use_natural_primary_keys', False) | |
self.start_serialization() | |
self.first = True | |
for obj in queryset: | |
self.start_object(obj) | |
# Use the concrete parent class' _meta instead of the object's _meta | |
# This is to avoid local_fields problems for proxy models. Refs #17717. | |
concrete_model = obj._meta.concrete_model | |
for field in concrete_model._meta.local_fields: | |
if field.serialize: | |
if field.rel is None: | |
if self.selected_fields is None or field.attname in self.selected_fields: | |
self.handle_field(obj, field) | |
else: | |
if self.selected_fields is None or field.attname[:-3] in self.selected_fields: | |
self.handle_fk_field(obj, field) | |
for field in concrete_model._meta.many_to_many: | |
if field.serialize: | |
if self.selected_fields is None or field.attname in self.selected_fields: | |
self.handle_m2m_field(obj, field) | |
# Add to make possible to serialize via json property from a object! | |
for name, field in obj.__class__.__dict__.items(): | |
if isinstance(field, property): | |
self.handle_property_field(obj, name) | |
self.end_object(obj) | |
if self.first: | |
self.first = False | |
self.end_serialization() | |
return self.getvalue() | |
def get_dump_object(self, obj): | |
current = {key: item if isinstance(item, dict) else escape(item) for key, item in self._current.items()} | |
return dict({'pk': smart_text(obj._get_pk_val(), strings_only=True), 'model': smart_text(obj._meta)}.items() | current.items()) | |
def handle_field(self, obj, field): | |
value = field._get_val_from_obj(obj) | |
# Protected types (i.e., primitives like None, numbers, dates, | |
# and Decimals) are passed through as is. All other values are | |
# converted to string first. | |
if is_protected_type(value): | |
self._current[field.name] = value | |
else: | |
# Changed to make it possible to get the value from a choice field, the LABEL value!! | |
value = field.value_to_string(obj) | |
if len(field.choices) > 0: | |
# Get the first value founded! | |
value = filter(None, map(lambda x: x[1] if str(x[0]) == value else None, field.choices)) | |
if value: | |
value = value[0] | |
self._current[field.name] = value | |
def handle_property_field(self, obj, name): | |
self._current[name] = getattr(obj, name) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment