Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I've actually had this same need, and I wrote a custom database field to handle it. Just save the following in a Python module in your project (say, for instance, a <code>fields.py</code> file in the appropriate app), and then import and use it:</p> <pre><code>class JSONField(models.TextField): """Specialized text field that holds JSON in the database, which is represented within Python as (usually) a dictionary.""" __metaclass__ = models.SubfieldBase def __init__(self, blank=True, default='{}', help_text='Specialized text field that holds JSON in the database, which is represented within Python as (usually) a dictionary.', *args, **kwargs): super(JSONField, self).__init__(*args, blank=blank, default=default, help_text=help_text, **kwargs) def get_prep_value(self, value): if type(value) in (str, unicode) and len(value) == 0: value = None return json.dumps(value) def formfield(self, form_class=JSONFormField, **kwargs): return super(JSONField, self).formfield(form_class=form_class, **kwargs) def bound_data(self, data, initial): return json.dumps(data) def to_python(self, value): # lists, dicts, ints, and booleans are clearly fine as is if type(value) not in (str, unicode): return value # empty strings were intended to be null if len(value) == 0: return None # NaN should become null; Python doesn't have a NaN value if value == 'NaN': return None # try to tell the difference between a "normal" string # and serialized JSON if value not in ('true', 'false', 'null') and (value[0] not in ('{', '[', '"') or value[-1] not in ('}', ']', '"')): return value # okay, this is a JSON-serialized string return json.loads(value) </code></pre> <p>A couple things. First, if you're using South, you'll need to explain to it how your custom field works:</p> <pre><code>from south.modelsinspector import add_introspection_rules add_introspection_rules([], [r'^feedmagnet\.tools\.fields\.models\.JSONField']) </code></pre> <p>Second, while I've done a lot of work to make sure that this custom field plays nice everywhere, such as cleanly going back and forth between the serialized format and Python. There's one place where it doesn't quite work right, which is when using it in conjunction with <code>manage.py dumpdata</code>, where it coalesces the Python to a string rather than dumping it into JSON, which isn't what you want. I've found this to be a minor problem in actual practice.</p> <p>More documentation on <a href="https://docs.djangoproject.com/en/1.3/howto/custom-model-fields/" rel="nofollow">writing custom model fields</a>.</p> <p>I assert that this is the single best and most obvious way to do this. Note that I also assume that you don't need to do <em>lookups</em> on this data -- e.g. you'll retrieve records based on other criteria, and this will come along with it. If you need to do lookups based on something in your JSON, make sure that it's a true SQL field (and make sure it's indexed!).</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload