2👍
Based on Django documentation: Writing custom model fields I’ve created simple field LongListAsTextField()
which extends default django.db.models.TextField
and converts list of longs from and to string with to_python
and get_prep_value
methods.
models.py
from __future__ import absolute_import
from django.db import models
from .fields import LongListAsTextField
class Record(models.Model):
parent_list = LongListAsTextField()
fields.py
from django.db import models
from django.utils.six import with_metaclass
class LongListAsTextField(with_metaclass(models.SubfieldBase, models.TextField)):
def to_python(self, value):
if isinstance(value, list):
return value
return [
long(val)
for val in value.split(',')
if val.isdigit()
]
def get_prep_value(self, value):
return ','.join([str(val) for val in value])
shell
Record(parent_list=[1,2]).save()
record = Record.objects.last()
record.parent_list # returns [1L, 2L]
0👍
Django does handle serialisation and storage of your list of longs into your database CharField
field without you doing anything. You don’t need a custom field; CharField
will convert the list using bytes()
, convert that to UTF8, and store it in your database. Your list may contain strings, numbers, tuples, lists, dicts, booleans, and None, or combinations thereof.
The problem you have is that when you retrieve the list from the database, it will be a unicode string, not a Python list. No problem, provided that you limit your data types to those mentioned above, you can use ast.literal_eval()
to safely unmarshall the list:
In your_app/models.py:
from django.db import models
class List(models.Model):
the_list = models.CharField(max_length=300, blank=True)
Then in python manage.py shell
:
>>> import ast
>>> from your_app.models import List
>>> original_list = [1, 2, 3, 444L, 1100L, -1234, 11.72, 'hi there', u'\u3030\u3000', {'a': 1, 'b': 2, 'c': [1, 2, 3]}, ('this', 'is', 'a', 'tuple'), True, None]
>>> List(the_list=original_list).save()
>>> retrieved_list = List.objects.last()
>>> retrieved_list
u"[1, 2, 3, 444L, 1100L, -1234, 11.72, 'hi there', u'\\u3030\\u3000', {'a': 1, 'c': [1, 2, 3], 'b': 2}, ('this', 'is', 'a', 'tuple'), True, None]"
>>> original_list == ast.literal_eval(retrieved_list.the_list)
True
Which shows that the list was successfully round-tripped through the database.