4đź‘Ť
We have a system of social-networks “backends” which do some generic stuff like “post message”, “get status”, “get friends” etc. The link between each backend class and user is django model, which keeps user, backend name and credentials. Now imagine how many auth systems are there: oauth, plain passwords, facebook’s obscure js stuff etc. This is where JSONField shines, we keep all backend-specif auth data in a dictionary on this model, which is stored in db as json, we can put anything into it no problem.
4đź‘Ť
You would use it to store… almost-arbitrary Python objects. In general there’s little reason to use it; JSON is safer and more portable.
4đź‘Ť
You can definitely substitute a PickledObjectField with JSON and some extra logic to create an object out of the JSON. At the end of the day, your use case, when considering to use a PickledObjectField or JSON+logic, is serializing a Python object into your database. If you can trust the data in the Python object, and know that it will always be serialize-able, you can reasonably use the PickledObjectField. In my case (I don’t use django’s ORM, but this should still apply), I have a couple different object types that can go into my PickledObjectField, and their definitions are constantly mutating. Rather than constantly updating my JSON parsing logic to create an object out of JSON values, I simply use a PickledObjectField to just store the different objects, and then later retrieve them in perfectly usable form (calling their functions). Caveat: If you store an object via PickledObjectField, then you change the object definition, and then you retrieve the object, the old object may have trouble fitting into the new object’s definition (depending on what you changed).
3đź‘Ť
The problems to be solved are the efficiency and the convenience of defining and handling a complex object consisting of many parts.
You can turn each part type into a Model and connect them via ForeignKeys.
Or you can turn each part type into a class, dictionary, list, tuple, enum or whathaveyou to your liking and use PickledObjectField
to store and retrieve the whole beast in one step.
That approach makes sense if you will never manipulate parts individually, only the complex object as a whole.
Real life example
In my application there are RQdef objects that represent essentially a type with a certain basic structure (if you are curious what they mean, look here).
- RQdefs consist of several Aspects and some fixed attributes.
- Aspects consist of one or more Facets and some fixed attributes.
- Facets consist of two or more Levels and some fixed attributes.
- Levels consist of a few fixed attributes.
- Overall, a typical RQdef will have about 20-40 parts.
- An RQdef is always completely constructed in a single step before it is stored in the database and it is henceforth never modified, only read (but read frequently).
PickledObjectField
is more convenient and much more efficient for this purpose than would be a set of four models and 20-40 objects for each RQdef.
- [Django]-Dealing with legacy django project in new localized projects
- [Django]-Django ORM: Joining QuerySets
- [Django]-Django-haystack elasticsearch as backend and searchengine
- [Django]-Setting number of gunicorn workers in django settings.py
- [Django]-Django app with fcgi works only in non daemonized mode