46đź‘Ť
If it’s really dictionary like arbitrary data you’re looking for you can probably use a two-level setup with one model that’s a container and another model that’s key-value pairs. You’d create an instance of the container, create each of the key-value instances, and associate the set of key-value instances with the container instance. Something like:
class Dicty(models.Model):
name = models.CharField(max_length=50)
class KeyVal(models.Model):
container = models.ForeignKey(Dicty, db_index=True)
key = models.CharField(max_length=240, db_index=True)
value = models.CharField(max_length=240, db_index=True)
It’s not pretty, but it’ll let you access/search the innards of the dictionary using the DB whereas a pickle/serialize solution will not.
21đź‘Ť
Another clean and fast solution can be found here: https://github.com/bradjasper/django-jsonfield
For convenience I copied the simple instructions.
Install
pip install jsonfield
Usage
from django.db import models
from jsonfield import JSONField
class MyModel(models.Model):
json = JSONField()
- [Django]-Test sending email without email server
- [Django]-How to get the ID of a just created record in Django?
- [Django]-Django return redirect() with parameters
18đź‘Ť
If you don’t need to query by any of this extra data, then you can store it as a serialized dictionary. Use repr
to turn the dictionary into a string, and eval
to turn the string back into a dictionary. Take care with eval that there’s no user data in the dictionary, or use a safe_eval
implementation.
For example, in the create
and update
methods of your views
, you can add:
if isinstance(request.data, dict) == False:
req_data = request.data.dict().copy()
else:
req_data = request.data.copy()
dict_key = 'request_parameter_that_has_a_dict_inside'
if dict_key in req_data.keys() and isinstance(req_data[dict_key], dict):
req_data[dict_key] = repr(req_data[dict_key])
- [Django]-Nginx doesn't serve static
- [Django]-How to use UUID
- [Django]-How to automatically login a user after registration in django
15đź‘Ť
I came to this post by google’s 4rth result to “django store object”
A little bit late, but django-picklefield looks like good solution to me.
Example from doc:
To use, just define a field in your model:
>>> from picklefield.fields import PickledObjectField
>>> class SomeObject(models.Model):
>>> args = PickledObjectField()
and assign whatever you like (as long as it’s picklable) to the field:
>>> obj = SomeObject()
>>> obj.args = ['fancy', {'objects': 'inside'}]
>>> obj.save()
- [Django]-How to set a Django model field's default value to a function call / callable (e.g., a date relative to the time of model object creation)
- [Django]-Django CSRF check failing with an Ajax POST request
- [Django]-Django AutoField with primary_key vs default pk
8đź‘Ť
As Ned answered, you won’t be able to query “some data” if you use the dictionary approach.
If you still need to store dictionaries then the best approach, by far, is the PickleField class documented in Marty Alchin’s new book Pro Django. This method uses Python class properties to pickle/unpickle a python object, only on demand, that is stored in a model field.
The basics of this approach is to use django’s contibute_to_class
method to dynamically add a new field to your model and uses getattr/setattr to do the serializing on demand.
One of the few online examples I could find that is similar is this definition of a JSONField.
- [Django]-Django: Catching Integrity Error and showing a customized message using template
- [Django]-How to reset migrations in Django 1.7
- [Django]-Django's forms.Form vs forms.ModelForm
6đź‘Ť
I’m not sure exactly sure of the nature of the problem you’re trying to solve, but it sounds curiously similar to Google App Engine’s BigTable Expando.
Expandos allow you to specify and store additional fields on an database-backed object instance at runtime. To quote from the docs:
import datetime
from google.appengine.ext import db
class Song(db.Expando):
title = db.StringProperty()
crazy = Song(title='Crazy like a diamond',
author='Lucy Sky',
publish_date='yesterday',
rating=5.0)
crazy.last_minute_note=db.Text('Get a train to the station.')
Google App Engine currently supports both Python and the Django framework. Might be worth looking into if this is the best way to express your models.
Traditional relational database models don’t have this kind of column-addition flexibility. If your datatypes are simple enough you could break from traditional RDBMS philosophy and hack values into a single column via serialization as @Ned Batchelder proposes; however, if you have to use an RDBMS, Django model inheritance is probably the way to go. Notably, it will create a one-to-one foreign key relation for each level of derivation.
- [Django]-Best way to integrate SqlAlchemy into a Django project
- [Django]-How to set the timezone in Django
- [Django]-Django: manage.py does not print stack trace for errors
6đź‘Ť
This question is old, but I was having the same problem, ended here and the chosen answer couldn’t solve my problem anymore.
If you want to store dictionaries in Django or REST Api, either to be used as objects in your front end, or because your data won’t necessarily have the same structure, the solution I used can help you.
When saving the data in your API, use json.dump() method to be able to store it in a proper json format, as described in this question.
If you use this structure, your data will already be in the appropriate json format to be called in the front end with JSON.parse() in your ajax (or whatever) call.
- [Django]-Automatic creation date for Django model form objects
- [Django]-Django substr / substring in templates
- [Django]-DateTimeField doesn't show in admin system
5đź‘Ť
I use a textfield and json.loads()
/json.dumps()
models.py
import json
from django.db import models
class Item(models.Model):
data = models.TextField(blank=True, null=True, default='{}')
def save(self, *args, **kwargs):
## load the current string and
## convert string to python dictionary
data_dict = json.loads(self.data)
## do something with the dictionary
for something in somethings:
data_dict[something] = some_function(something)
## if it is empty, save it back to a '{}' string,
## if it is not empty, convert the dictionary back to a json string
if not data_dict:
self.data = '{}'
else:
self.data = json.dumps(data_dict)
super(Item, self).save(*args, **kwargs)
- [Django]-Django queries: how to filter objects to exclude id which is in a list?
- [Django]-Fastest way to get the first object from a queryset in django?
- [Django]-Django – view sql query without publishing migrations
3đź‘Ť
Being “not equal to all instances of the model” sounds to me like a good match for a “Schema-free database”. CouchDB is the poster child for that approach and you might consider that.
In a project I moved several tables which never played very nice with the Django ORM over to CouchDB and I’m quite happy with that. I use couchdb-python without any of the Django-specific CouchDB modules. A description of the data model can be found here. The movement from five “models” in Django to 3 “models” in Django and one CouchDB “database” actually slightly reduced the total lines of code in my application.
- [Django]-Django testing: Test the initial value of a form field
- [Django]-How to show processing animation / spinner during ajax request?
- [Django]-Django filter queryset __in for *every* item in list
3đź‘Ť
Django-Geo includes a “DictionaryField” you might find helpful:
http://code.google.com/p/django-geo/source/browse/trunk/fields.py?r=13#49
In general, if you don’t need to query across the data use a denormalized approach to avoid extra queries. User settings are a pretty good example!
- [Django]-Django: Get list of model fields?
- [Django]-What is the difference between {% load staticfiles %} and {% load static %}
- [Django]-Django-taggit – how do I display the tags related to each record
3đź‘Ť
I agree that you need to refrain stuffing otherwise structured data into a single column. But if you must do that, Django has an XMLField build-in.
There’s also JSONField at Django snipplets.
- [Django]-Django Installed Apps Location
- [Django]-Why do we need to use rabbitmq
- [Django]-Django: Model Form "object has no attribute 'cleaned_data'"
3đź‘Ť
I know this is an old question, but today (2021) the cleanest alternative is to use the native JSONfield (since django 3.1)
docs: https://docs.djangoproject.com/en/3.2/ref/models/fields/#django.db.models.JSONField
you just create a field in the model called jsonfield inside the class model and voilá
- [Django]-Django – How to pass several arguments to the url template tag
- [Django]-Django DoesNotExist
- [Django]-POST jQuery array to Django
1đź‘Ť
Think it over, and find the commonalities of each data set… then define your model. It may require the use of subclasses or not. Foreign keys representing commonalities aren’t to be avoided, but encouraged when they make sense.
Stuffing random data into a SQL table is not smart, unless it’s truly non-relational data. If that’s the case, define your problem and we may be able to help.
- [Django]-Django Queryset with filtering on reverse foreign key
- [Django]-Django – Reverse for '' not found. '' is not a valid view function or pattern name
- [Django]-Django manage.py runserver invalid syntax
1đź‘Ť
If you are using Postgres, you can use an hstore field: https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#hstorefield.
- [Django]-What is the path that Django uses for locating and loading templates?
- [Django]-How to tell if a task has already been queued in django-celery?
- [Django]-How can I run a celery periodic task from the shell manually?