简体   繁体   中英

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM