Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning verbose names from query set when using json serializer

Is it possible to call

tasks = models.Conference.objects.filter(location_id=key)
data = serializers.serialize("json", tasks)

and have it return the verbose field names rather than the variable names?

like image 278
RustyShackleford Avatar asked May 27 '26 22:05

RustyShackleford


1 Answers

One way to accomplish this, is by monkey patching the methods within the django.core.serializers.python.Serializer class to return each fields verbose_name opposed to the standard name attribute.

Take for example the following code...

models.py

from django.db import models

class RelatedNode(models.Model):
    name = models.CharField(max_length=100, verbose_name="related node")

class Node(models.Model):
    name = models.CharField(max_length=100, verbose_name="verbose name")
    related_node = models.ForeignKey(RelatedNode, verbose_name="verbose fk related node", related_name="related_node")
    related_nodes = models.ManyToManyField(RelatedNode, verbose_name="verbose related m2m nodes", related_name="related_nodes")

I create these model objects within the database...

RelatedNode.objects.create(name='related_node_1')
RelatedNode.objects.create(name='related_node_2')
RelatedNode.objects.create(name='related_node_fk')
Node.objects.create(name='node_1', related_node=RelatedNode.objects.get(name='related_node_fk'))
Node.objects.all()[0].related_nodes.add(RelatedNode.objects.get(name='related_node_1'))
Node.objects.all()[0].related_nodes.add(RelatedNode.objects.get(name='related_node_2'))

views.py

from testing.models import Node
from django.utils.encoding import smart_text, is_protected_type
from django.core.serializers.python import Serializer
from django.core import serializers

def monkey_patch_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.verbose_name] = value
    else:
        self._current[field.verbose_name] = field.value_to_string(obj)

def monkey_patch_handle_fk_field(self, obj, field):
    if self.use_natural_foreign_keys and hasattr(field.rel.to, 'natural_key'):
        related = getattr(obj, field.name)
        if related:
            value = related.natural_key()
        else:
            value = None
    else:
        value = getattr(obj, field.get_attname())
    self._current[field.verbose_name] = value

def monkey_patch_handle_m2m_field(self, obj, field):
    if field.rel.through._meta.auto_created:
        if self.use_natural_foreign_keys and hasattr(field.rel.to, 'natural_key'):
            m2m_value = lambda value: value.natural_key()
        else:
            m2m_value = lambda value: smart_text(value._get_pk_val(), strings_only=True)
        self._current[field.verbose_name] = [m2m_value(related)
                           for related in getattr(obj, field.name).iterator()]

Serializer.handle_field = monkey_patch_handle_field
Serializer.handle_fk_field = monkey_patch_handle_fk_field
Serializer.handle_m2m_field = monkey_patch_handle_m2m_field


serializers.serialize('json', Node.objects.all())

This outputs for me...

u'[{"fields": {"verbose fk related node": 3, "verbose related m2m nodes": [1, 2], "verbose name": "node_1"}, "model": "testing.node", "pk": 1}]'

As we could see, this actually gives us back the verbose_name of each field as keys in the returned dictionaries.

like image 74
Kevin Cherepski Avatar answered May 30 '26 11:05

Kevin Cherepski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!