Django: List field in model?
In my model, I want a field that has a list of triplets. e.g. `[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]. Is there a field that can store this data in the database?
django django-orm
add a comment |
In my model, I want a field that has a list of triplets. e.g. `[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]. Is there a field that can store this data in the database?
django django-orm
1
Which database are you using?
– erthalion
Mar 12 '14 at 4:25
add a comment |
In my model, I want a field that has a list of triplets. e.g. `[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]. Is there a field that can store this data in the database?
django django-orm
In my model, I want a field that has a list of triplets. e.g. `[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]. Is there a field that can store this data in the database?
django django-orm
django django-orm
edited Jan 2 '17 at 15:11
Risadinha
9,25115562
9,25115562
asked Mar 12 '14 at 1:34
KarnivaurusKarnivaurus
5,6193086159
5,6193086159
1
Which database are you using?
– erthalion
Mar 12 '14 at 4:25
add a comment |
1
Which database are you using?
– erthalion
Mar 12 '14 at 4:25
1
1
Which database are you using?
– erthalion
Mar 12 '14 at 4:25
Which database are you using?
– erthalion
Mar 12 '14 at 4:25
add a comment |
9 Answers
9
active
oldest
votes
You can convert it into string by using JSON and store it as string.
For example,
In [3]: json.dumps([[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]])
Out[3]: '[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]'
You can add a method into your class to convert it automatically for you.
import json
class Foobar(models.Model):
foo = models.CharField(max_length=200)
def set_foo(self, x):
self.foo = json.dumps(x)
def get_foo(self):
return json.loads(self.foo)
If you're using Django 1.9 and postgresql, there is a new class called JSONField, you should use it instead. Here is a link to it
There is a good talk about PostgreSQL JSONs and Arrays on youtube. Watch it, it has very good information.
2
Is there a specific reason that we may use json serialization instead of a custom List field (like the second answer in this thread)? I'm having this concern performance-wise mainly but also I'd like to know if there is anything else that I should notice before choosing between these two approaches. Thanks in advance!
– Kostas Livieratos
Jul 3 '15 at 15:18
1
Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json.
– Ahmed
Jul 3 '15 at 17:13
json.dumps will make a full json conversion changing things like None --> null. I don't get why to use that when you want a list->string conversion
– chefarov
Jan 24 '17 at 14:00
You can use JSONField natively if you're running postgresql
– Ahmed
Jan 24 '17 at 15:25
2
In Django 1.10 and above, there's a newArrayField
field you can use. See answer below.
– madmanick
Apr 17 '17 at 2:35
|
show 3 more comments
If you are using PostgreSQL, you can use ArrayField with a nested ArrayField: https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/
This way, the data structure will be known to the underlying database. Also, the ORM brings special functionality for it.
Note that you will have to create a GIN index by yourself, though (see the above link, further down: https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/#indexing-arrayfield).
add a comment |
If you're using a more modern version of Django like 1.10 and your DB is Postgres, there is a new ArrayField that is better to use than django-taggit or other alternatives, as it's native to the Django framework.
from django.db import models
from django.contrib.postgres.fields import ArrayField
class ChessBoard(models.Model):
board = ArrayField(
ArrayField(
models.CharField(max_length=10, blank=True),
size=8,
),
size=8,
)
1
Thanks! Looks like its postgres specific but a great one!
– Anupam
Jul 13 '17 at 4:48
add a comment |
I think it will help you.
from django.db import models
import ast
class ListField(models.TextField):
__metaclass__ = models.SubfieldBase
description = "Stores a python list"
def __init__(self, *args, **kwargs):
super(ListField, self).__init__(*args, **kwargs)
def to_python(self, value):
if not value:
value =
if isinstance(value, list):
return value
return ast.literal_eval(value)
def get_prep_value(self, value):
if value is None:
return value
return unicode(value)
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value)
class ListModel(models.Model):
test_list = ListField()
Example :
>>> ListModel.objects.create(test_list= [[1,2,3], [2,3,4,4]])
>>> ListModel.objects.get(id=1)
>>> o = ListModel.objects.get(id=1)
>>> o.id
1L
>>> o.test_list
[[1, 2, 3], [2, 3, 4, 4]]
>>>
I am using python 3.5 so there are couple of issues - unicode is now str and I am getting an error ..create() takes 1 positional argument but 2 were given
– Taposh DuttaRoy
Mar 1 '17 at 1:40
paste your create query code.
– Prashant Gaur
Mar 1 '17 at 12:19
I used this solution in django 1.7. Now i upgraded it to 1.9.12 But it is not working. What change should I made for make it workable in django 1.9.12
– Soham Navadiya
May 29 '17 at 13:56
Please share error you are getting , also which version of python you are using ?
– Prashant Gaur
May 30 '17 at 5:54
add a comment |
Just use a JSON field that these third-party packages provide:
- django-jsonfield
- django-annoying
In this case, you don't need to care about the field value serialization - it'll happen under-the-hood.
Hope that helps.
add a comment |
You can flatten the list and then store the values to a CommaSeparatedIntegerField. When you read back from the database, just group the values back into threes.
Disclaimer: according to database normalization theory, it is better not to store collections in single fields; instead you would be encouraged to store the values in those triplets in their own fields and link them via foreign keys. In the real world, though, sometimes that is too cumbersome/slow.
1
Note that this is deprecated as of Django 1.9 per the link in the article.
– phoenix
Apr 11 '16 at 0:50
add a comment |
If you are using Google App Engine or MongoDB as your backend, and you are using the djangoappengine
library, there is a built in ListField
that does exactly what you want. Further, it's easy to query the Listfield to find all objects that contain an element in the list.
add a comment |
With my current reputation I have no ability to comment, so I choose answer referencing comments for sample code in reply by Prashant Gaur (thanks, Gaur - this was helpful!) - his sample is for python2, since python3 has no
unicodemethod.
The replacement below for function
get_prep_value(self, value):should work with Django running with python3 (I'll use this code soon - yet not tested).
Note, though, that I'm passing
encoding='utf-8', errors='ignore'parameters to
decode()and
unicode() methods. Encoding should match your Django settings.py configuration and passing
errors='ignore'is optional (and may result in silent data loss instead of exception whith misconfigured django in rare cases).
import sys
...
def get_prep_value(self, value):
if value is None:
return value
if sys.version_info[0] >= 3:
if isinstance(out_data, type(b'')):
return value.decode(encoding='utf-8', errors='ignore')
else:
if isinstance(out_data, type(b'')):
return unicode(value, encoding='utf-8', errors='ignore')
return str(value)
...
add a comment |
It's quite an old topic, but since it is returned when searching for "django list field" I'll share the custom django list field code I modified to work with Python 3 and Django 2. It supports the admin interface now and not uses eval (which is a huge security breach in Prashant Gaur's code).
from django.db import models
from typing import Iterable
class ListField(models.TextField):
"""
A custom Django field to represent lists as comma separated strings
"""
def __init__(self, *args, **kwargs):
self.token = kwargs.pop('token', ',')
super().__init__(*args, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
kwargs['token'] = self.token
return name, path, args, kwargs
def to_python(self, value):
class SubList(list):
def __init__(self, token, *args):
self.token = token
super().__init__(*args)
def __str__(self):
return self.token.join(self)
if isinstance(value, list):
return value
if value is None:
return SubList(self.token)
return SubList(self.token, value.split(self.token))
def from_db_value(self, value, expression, connection):
return self.to_python(value)
def get_prep_value(self, value):
if not value:
return
assert(isinstance(value, Iterable))
return self.token.join(value)
def value_to_string(self, obj):
value = self.value_from_object(obj)
return self.get_prep_value(value)
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f22340258%2fdjango-list-field-in-model%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
9 Answers
9
active
oldest
votes
9 Answers
9
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can convert it into string by using JSON and store it as string.
For example,
In [3]: json.dumps([[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]])
Out[3]: '[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]'
You can add a method into your class to convert it automatically for you.
import json
class Foobar(models.Model):
foo = models.CharField(max_length=200)
def set_foo(self, x):
self.foo = json.dumps(x)
def get_foo(self):
return json.loads(self.foo)
If you're using Django 1.9 and postgresql, there is a new class called JSONField, you should use it instead. Here is a link to it
There is a good talk about PostgreSQL JSONs and Arrays on youtube. Watch it, it has very good information.
2
Is there a specific reason that we may use json serialization instead of a custom List field (like the second answer in this thread)? I'm having this concern performance-wise mainly but also I'd like to know if there is anything else that I should notice before choosing between these two approaches. Thanks in advance!
– Kostas Livieratos
Jul 3 '15 at 15:18
1
Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json.
– Ahmed
Jul 3 '15 at 17:13
json.dumps will make a full json conversion changing things like None --> null. I don't get why to use that when you want a list->string conversion
– chefarov
Jan 24 '17 at 14:00
You can use JSONField natively if you're running postgresql
– Ahmed
Jan 24 '17 at 15:25
2
In Django 1.10 and above, there's a newArrayField
field you can use. See answer below.
– madmanick
Apr 17 '17 at 2:35
|
show 3 more comments
You can convert it into string by using JSON and store it as string.
For example,
In [3]: json.dumps([[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]])
Out[3]: '[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]'
You can add a method into your class to convert it automatically for you.
import json
class Foobar(models.Model):
foo = models.CharField(max_length=200)
def set_foo(self, x):
self.foo = json.dumps(x)
def get_foo(self):
return json.loads(self.foo)
If you're using Django 1.9 and postgresql, there is a new class called JSONField, you should use it instead. Here is a link to it
There is a good talk about PostgreSQL JSONs and Arrays on youtube. Watch it, it has very good information.
2
Is there a specific reason that we may use json serialization instead of a custom List field (like the second answer in this thread)? I'm having this concern performance-wise mainly but also I'd like to know if there is anything else that I should notice before choosing between these two approaches. Thanks in advance!
– Kostas Livieratos
Jul 3 '15 at 15:18
1
Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json.
– Ahmed
Jul 3 '15 at 17:13
json.dumps will make a full json conversion changing things like None --> null. I don't get why to use that when you want a list->string conversion
– chefarov
Jan 24 '17 at 14:00
You can use JSONField natively if you're running postgresql
– Ahmed
Jan 24 '17 at 15:25
2
In Django 1.10 and above, there's a newArrayField
field you can use. See answer below.
– madmanick
Apr 17 '17 at 2:35
|
show 3 more comments
You can convert it into string by using JSON and store it as string.
For example,
In [3]: json.dumps([[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]])
Out[3]: '[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]'
You can add a method into your class to convert it automatically for you.
import json
class Foobar(models.Model):
foo = models.CharField(max_length=200)
def set_foo(self, x):
self.foo = json.dumps(x)
def get_foo(self):
return json.loads(self.foo)
If you're using Django 1.9 and postgresql, there is a new class called JSONField, you should use it instead. Here is a link to it
There is a good talk about PostgreSQL JSONs and Arrays on youtube. Watch it, it has very good information.
You can convert it into string by using JSON and store it as string.
For example,
In [3]: json.dumps([[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]])
Out[3]: '[[1, 3, 4], [4, 2, 6], [8, 12, 3], [3, 3, 9]]'
You can add a method into your class to convert it automatically for you.
import json
class Foobar(models.Model):
foo = models.CharField(max_length=200)
def set_foo(self, x):
self.foo = json.dumps(x)
def get_foo(self):
return json.loads(self.foo)
If you're using Django 1.9 and postgresql, there is a new class called JSONField, you should use it instead. Here is a link to it
There is a good talk about PostgreSQL JSONs and Arrays on youtube. Watch it, it has very good information.
edited Feb 6 '18 at 23:27
answered Mar 12 '14 at 6:47
AhmedAhmed
1,5271023
1,5271023
2
Is there a specific reason that we may use json serialization instead of a custom List field (like the second answer in this thread)? I'm having this concern performance-wise mainly but also I'd like to know if there is anything else that I should notice before choosing between these two approaches. Thanks in advance!
– Kostas Livieratos
Jul 3 '15 at 15:18
1
Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json.
– Ahmed
Jul 3 '15 at 17:13
json.dumps will make a full json conversion changing things like None --> null. I don't get why to use that when you want a list->string conversion
– chefarov
Jan 24 '17 at 14:00
You can use JSONField natively if you're running postgresql
– Ahmed
Jan 24 '17 at 15:25
2
In Django 1.10 and above, there's a newArrayField
field you can use. See answer below.
– madmanick
Apr 17 '17 at 2:35
|
show 3 more comments
2
Is there a specific reason that we may use json serialization instead of a custom List field (like the second answer in this thread)? I'm having this concern performance-wise mainly but also I'd like to know if there is anything else that I should notice before choosing between these two approaches. Thanks in advance!
– Kostas Livieratos
Jul 3 '15 at 15:18
1
Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json.
– Ahmed
Jul 3 '15 at 17:13
json.dumps will make a full json conversion changing things like None --> null. I don't get why to use that when you want a list->string conversion
– chefarov
Jan 24 '17 at 14:00
You can use JSONField natively if you're running postgresql
– Ahmed
Jan 24 '17 at 15:25
2
In Django 1.10 and above, there's a newArrayField
field you can use. See answer below.
– madmanick
Apr 17 '17 at 2:35
2
2
Is there a specific reason that we may use json serialization instead of a custom List field (like the second answer in this thread)? I'm having this concern performance-wise mainly but also I'd like to know if there is anything else that I should notice before choosing between these two approaches. Thanks in advance!
– Kostas Livieratos
Jul 3 '15 at 15:18
Is there a specific reason that we may use json serialization instead of a custom List field (like the second answer in this thread)? I'm having this concern performance-wise mainly but also I'd like to know if there is anything else that I should notice before choosing between these two approaches. Thanks in advance!
– Kostas Livieratos
Jul 3 '15 at 15:18
1
1
Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json.
– Ahmed
Jul 3 '15 at 17:13
Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json.
– Ahmed
Jul 3 '15 at 17:13
json.dumps will make a full json conversion changing things like None --> null. I don't get why to use that when you want a list->string conversion
– chefarov
Jan 24 '17 at 14:00
json.dumps will make a full json conversion changing things like None --> null. I don't get why to use that when you want a list->string conversion
– chefarov
Jan 24 '17 at 14:00
You can use JSONField natively if you're running postgresql
– Ahmed
Jan 24 '17 at 15:25
You can use JSONField natively if you're running postgresql
– Ahmed
Jan 24 '17 at 15:25
2
2
In Django 1.10 and above, there's a new
ArrayField
field you can use. See answer below.– madmanick
Apr 17 '17 at 2:35
In Django 1.10 and above, there's a new
ArrayField
field you can use. See answer below.– madmanick
Apr 17 '17 at 2:35
|
show 3 more comments
If you are using PostgreSQL, you can use ArrayField with a nested ArrayField: https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/
This way, the data structure will be known to the underlying database. Also, the ORM brings special functionality for it.
Note that you will have to create a GIN index by yourself, though (see the above link, further down: https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/#indexing-arrayfield).
add a comment |
If you are using PostgreSQL, you can use ArrayField with a nested ArrayField: https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/
This way, the data structure will be known to the underlying database. Also, the ORM brings special functionality for it.
Note that you will have to create a GIN index by yourself, though (see the above link, further down: https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/#indexing-arrayfield).
add a comment |
If you are using PostgreSQL, you can use ArrayField with a nested ArrayField: https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/
This way, the data structure will be known to the underlying database. Also, the ORM brings special functionality for it.
Note that you will have to create a GIN index by yourself, though (see the above link, further down: https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/#indexing-arrayfield).
If you are using PostgreSQL, you can use ArrayField with a nested ArrayField: https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/
This way, the data structure will be known to the underlying database. Also, the ORM brings special functionality for it.
Note that you will have to create a GIN index by yourself, though (see the above link, further down: https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/#indexing-arrayfield).
answered Jun 13 '15 at 16:01
RisadinhaRisadinha
9,25115562
9,25115562
add a comment |
add a comment |
If you're using a more modern version of Django like 1.10 and your DB is Postgres, there is a new ArrayField that is better to use than django-taggit or other alternatives, as it's native to the Django framework.
from django.db import models
from django.contrib.postgres.fields import ArrayField
class ChessBoard(models.Model):
board = ArrayField(
ArrayField(
models.CharField(max_length=10, blank=True),
size=8,
),
size=8,
)
1
Thanks! Looks like its postgres specific but a great one!
– Anupam
Jul 13 '17 at 4:48
add a comment |
If you're using a more modern version of Django like 1.10 and your DB is Postgres, there is a new ArrayField that is better to use than django-taggit or other alternatives, as it's native to the Django framework.
from django.db import models
from django.contrib.postgres.fields import ArrayField
class ChessBoard(models.Model):
board = ArrayField(
ArrayField(
models.CharField(max_length=10, blank=True),
size=8,
),
size=8,
)
1
Thanks! Looks like its postgres specific but a great one!
– Anupam
Jul 13 '17 at 4:48
add a comment |
If you're using a more modern version of Django like 1.10 and your DB is Postgres, there is a new ArrayField that is better to use than django-taggit or other alternatives, as it's native to the Django framework.
from django.db import models
from django.contrib.postgres.fields import ArrayField
class ChessBoard(models.Model):
board = ArrayField(
ArrayField(
models.CharField(max_length=10, blank=True),
size=8,
),
size=8,
)
If you're using a more modern version of Django like 1.10 and your DB is Postgres, there is a new ArrayField that is better to use than django-taggit or other alternatives, as it's native to the Django framework.
from django.db import models
from django.contrib.postgres.fields import ArrayField
class ChessBoard(models.Model):
board = ArrayField(
ArrayField(
models.CharField(max_length=10, blank=True),
size=8,
),
size=8,
)
edited Oct 24 '17 at 17:39
answered Dec 8 '16 at 19:35
madmanickmadmanick
72858
72858
1
Thanks! Looks like its postgres specific but a great one!
– Anupam
Jul 13 '17 at 4:48
add a comment |
1
Thanks! Looks like its postgres specific but a great one!
– Anupam
Jul 13 '17 at 4:48
1
1
Thanks! Looks like its postgres specific but a great one!
– Anupam
Jul 13 '17 at 4:48
Thanks! Looks like its postgres specific but a great one!
– Anupam
Jul 13 '17 at 4:48
add a comment |
I think it will help you.
from django.db import models
import ast
class ListField(models.TextField):
__metaclass__ = models.SubfieldBase
description = "Stores a python list"
def __init__(self, *args, **kwargs):
super(ListField, self).__init__(*args, **kwargs)
def to_python(self, value):
if not value:
value =
if isinstance(value, list):
return value
return ast.literal_eval(value)
def get_prep_value(self, value):
if value is None:
return value
return unicode(value)
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value)
class ListModel(models.Model):
test_list = ListField()
Example :
>>> ListModel.objects.create(test_list= [[1,2,3], [2,3,4,4]])
>>> ListModel.objects.get(id=1)
>>> o = ListModel.objects.get(id=1)
>>> o.id
1L
>>> o.test_list
[[1, 2, 3], [2, 3, 4, 4]]
>>>
I am using python 3.5 so there are couple of issues - unicode is now str and I am getting an error ..create() takes 1 positional argument but 2 were given
– Taposh DuttaRoy
Mar 1 '17 at 1:40
paste your create query code.
– Prashant Gaur
Mar 1 '17 at 12:19
I used this solution in django 1.7. Now i upgraded it to 1.9.12 But it is not working. What change should I made for make it workable in django 1.9.12
– Soham Navadiya
May 29 '17 at 13:56
Please share error you are getting , also which version of python you are using ?
– Prashant Gaur
May 30 '17 at 5:54
add a comment |
I think it will help you.
from django.db import models
import ast
class ListField(models.TextField):
__metaclass__ = models.SubfieldBase
description = "Stores a python list"
def __init__(self, *args, **kwargs):
super(ListField, self).__init__(*args, **kwargs)
def to_python(self, value):
if not value:
value =
if isinstance(value, list):
return value
return ast.literal_eval(value)
def get_prep_value(self, value):
if value is None:
return value
return unicode(value)
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value)
class ListModel(models.Model):
test_list = ListField()
Example :
>>> ListModel.objects.create(test_list= [[1,2,3], [2,3,4,4]])
>>> ListModel.objects.get(id=1)
>>> o = ListModel.objects.get(id=1)
>>> o.id
1L
>>> o.test_list
[[1, 2, 3], [2, 3, 4, 4]]
>>>
I am using python 3.5 so there are couple of issues - unicode is now str and I am getting an error ..create() takes 1 positional argument but 2 were given
– Taposh DuttaRoy
Mar 1 '17 at 1:40
paste your create query code.
– Prashant Gaur
Mar 1 '17 at 12:19
I used this solution in django 1.7. Now i upgraded it to 1.9.12 But it is not working. What change should I made for make it workable in django 1.9.12
– Soham Navadiya
May 29 '17 at 13:56
Please share error you are getting , also which version of python you are using ?
– Prashant Gaur
May 30 '17 at 5:54
add a comment |
I think it will help you.
from django.db import models
import ast
class ListField(models.TextField):
__metaclass__ = models.SubfieldBase
description = "Stores a python list"
def __init__(self, *args, **kwargs):
super(ListField, self).__init__(*args, **kwargs)
def to_python(self, value):
if not value:
value =
if isinstance(value, list):
return value
return ast.literal_eval(value)
def get_prep_value(self, value):
if value is None:
return value
return unicode(value)
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value)
class ListModel(models.Model):
test_list = ListField()
Example :
>>> ListModel.objects.create(test_list= [[1,2,3], [2,3,4,4]])
>>> ListModel.objects.get(id=1)
>>> o = ListModel.objects.get(id=1)
>>> o.id
1L
>>> o.test_list
[[1, 2, 3], [2, 3, 4, 4]]
>>>
I think it will help you.
from django.db import models
import ast
class ListField(models.TextField):
__metaclass__ = models.SubfieldBase
description = "Stores a python list"
def __init__(self, *args, **kwargs):
super(ListField, self).__init__(*args, **kwargs)
def to_python(self, value):
if not value:
value =
if isinstance(value, list):
return value
return ast.literal_eval(value)
def get_prep_value(self, value):
if value is None:
return value
return unicode(value)
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value)
class ListModel(models.Model):
test_list = ListField()
Example :
>>> ListModel.objects.create(test_list= [[1,2,3], [2,3,4,4]])
>>> ListModel.objects.get(id=1)
>>> o = ListModel.objects.get(id=1)
>>> o.id
1L
>>> o.test_list
[[1, 2, 3], [2, 3, 4, 4]]
>>>
edited May 30 '17 at 5:46
answered Mar 12 '14 at 6:35
Prashant GaurPrashant Gaur
4,84673857
4,84673857
I am using python 3.5 so there are couple of issues - unicode is now str and I am getting an error ..create() takes 1 positional argument but 2 were given
– Taposh DuttaRoy
Mar 1 '17 at 1:40
paste your create query code.
– Prashant Gaur
Mar 1 '17 at 12:19
I used this solution in django 1.7. Now i upgraded it to 1.9.12 But it is not working. What change should I made for make it workable in django 1.9.12
– Soham Navadiya
May 29 '17 at 13:56
Please share error you are getting , also which version of python you are using ?
– Prashant Gaur
May 30 '17 at 5:54
add a comment |
I am using python 3.5 so there are couple of issues - unicode is now str and I am getting an error ..create() takes 1 positional argument but 2 were given
– Taposh DuttaRoy
Mar 1 '17 at 1:40
paste your create query code.
– Prashant Gaur
Mar 1 '17 at 12:19
I used this solution in django 1.7. Now i upgraded it to 1.9.12 But it is not working. What change should I made for make it workable in django 1.9.12
– Soham Navadiya
May 29 '17 at 13:56
Please share error you are getting , also which version of python you are using ?
– Prashant Gaur
May 30 '17 at 5:54
I am using python 3.5 so there are couple of issues - unicode is now str and I am getting an error ..create() takes 1 positional argument but 2 were given
– Taposh DuttaRoy
Mar 1 '17 at 1:40
I am using python 3.5 so there are couple of issues - unicode is now str and I am getting an error ..create() takes 1 positional argument but 2 were given
– Taposh DuttaRoy
Mar 1 '17 at 1:40
paste your create query code.
– Prashant Gaur
Mar 1 '17 at 12:19
paste your create query code.
– Prashant Gaur
Mar 1 '17 at 12:19
I used this solution in django 1.7. Now i upgraded it to 1.9.12 But it is not working. What change should I made for make it workable in django 1.9.12
– Soham Navadiya
May 29 '17 at 13:56
I used this solution in django 1.7. Now i upgraded it to 1.9.12 But it is not working. What change should I made for make it workable in django 1.9.12
– Soham Navadiya
May 29 '17 at 13:56
Please share error you are getting , also which version of python you are using ?
– Prashant Gaur
May 30 '17 at 5:54
Please share error you are getting , also which version of python you are using ?
– Prashant Gaur
May 30 '17 at 5:54
add a comment |
Just use a JSON field that these third-party packages provide:
- django-jsonfield
- django-annoying
In this case, you don't need to care about the field value serialization - it'll happen under-the-hood.
Hope that helps.
add a comment |
Just use a JSON field that these third-party packages provide:
- django-jsonfield
- django-annoying
In this case, you don't need to care about the field value serialization - it'll happen under-the-hood.
Hope that helps.
add a comment |
Just use a JSON field that these third-party packages provide:
- django-jsonfield
- django-annoying
In this case, you don't need to care about the field value serialization - it'll happen under-the-hood.
Hope that helps.
Just use a JSON field that these third-party packages provide:
- django-jsonfield
- django-annoying
In this case, you don't need to care about the field value serialization - it'll happen under-the-hood.
Hope that helps.
answered Mar 12 '14 at 17:49
alecxealecxe
327k71644868
327k71644868
add a comment |
add a comment |
You can flatten the list and then store the values to a CommaSeparatedIntegerField. When you read back from the database, just group the values back into threes.
Disclaimer: according to database normalization theory, it is better not to store collections in single fields; instead you would be encouraged to store the values in those triplets in their own fields and link them via foreign keys. In the real world, though, sometimes that is too cumbersome/slow.
1
Note that this is deprecated as of Django 1.9 per the link in the article.
– phoenix
Apr 11 '16 at 0:50
add a comment |
You can flatten the list and then store the values to a CommaSeparatedIntegerField. When you read back from the database, just group the values back into threes.
Disclaimer: according to database normalization theory, it is better not to store collections in single fields; instead you would be encouraged to store the values in those triplets in their own fields and link them via foreign keys. In the real world, though, sometimes that is too cumbersome/slow.
1
Note that this is deprecated as of Django 1.9 per the link in the article.
– phoenix
Apr 11 '16 at 0:50
add a comment |
You can flatten the list and then store the values to a CommaSeparatedIntegerField. When you read back from the database, just group the values back into threes.
Disclaimer: according to database normalization theory, it is better not to store collections in single fields; instead you would be encouraged to store the values in those triplets in their own fields and link them via foreign keys. In the real world, though, sometimes that is too cumbersome/slow.
You can flatten the list and then store the values to a CommaSeparatedIntegerField. When you read back from the database, just group the values back into threes.
Disclaimer: according to database normalization theory, it is better not to store collections in single fields; instead you would be encouraged to store the values in those triplets in their own fields and link them via foreign keys. In the real world, though, sometimes that is too cumbersome/slow.
answered Mar 12 '14 at 6:26
RexERexE
7,875124970
7,875124970
1
Note that this is deprecated as of Django 1.9 per the link in the article.
– phoenix
Apr 11 '16 at 0:50
add a comment |
1
Note that this is deprecated as of Django 1.9 per the link in the article.
– phoenix
Apr 11 '16 at 0:50
1
1
Note that this is deprecated as of Django 1.9 per the link in the article.
– phoenix
Apr 11 '16 at 0:50
Note that this is deprecated as of Django 1.9 per the link in the article.
– phoenix
Apr 11 '16 at 0:50
add a comment |
If you are using Google App Engine or MongoDB as your backend, and you are using the djangoappengine
library, there is a built in ListField
that does exactly what you want. Further, it's easy to query the Listfield to find all objects that contain an element in the list.
add a comment |
If you are using Google App Engine or MongoDB as your backend, and you are using the djangoappengine
library, there is a built in ListField
that does exactly what you want. Further, it's easy to query the Listfield to find all objects that contain an element in the list.
add a comment |
If you are using Google App Engine or MongoDB as your backend, and you are using the djangoappengine
library, there is a built in ListField
that does exactly what you want. Further, it's easy to query the Listfield to find all objects that contain an element in the list.
If you are using Google App Engine or MongoDB as your backend, and you are using the djangoappengine
library, there is a built in ListField
that does exactly what you want. Further, it's easy to query the Listfield to find all objects that contain an element in the list.
answered Mar 25 '16 at 13:23
speedplanespeedplane
9,243964109
9,243964109
add a comment |
add a comment |
With my current reputation I have no ability to comment, so I choose answer referencing comments for sample code in reply by Prashant Gaur (thanks, Gaur - this was helpful!) - his sample is for python2, since python3 has no
unicodemethod.
The replacement below for function
get_prep_value(self, value):should work with Django running with python3 (I'll use this code soon - yet not tested).
Note, though, that I'm passing
encoding='utf-8', errors='ignore'parameters to
decode()and
unicode() methods. Encoding should match your Django settings.py configuration and passing
errors='ignore'is optional (and may result in silent data loss instead of exception whith misconfigured django in rare cases).
import sys
...
def get_prep_value(self, value):
if value is None:
return value
if sys.version_info[0] >= 3:
if isinstance(out_data, type(b'')):
return value.decode(encoding='utf-8', errors='ignore')
else:
if isinstance(out_data, type(b'')):
return unicode(value, encoding='utf-8', errors='ignore')
return str(value)
...
add a comment |
With my current reputation I have no ability to comment, so I choose answer referencing comments for sample code in reply by Prashant Gaur (thanks, Gaur - this was helpful!) - his sample is for python2, since python3 has no
unicodemethod.
The replacement below for function
get_prep_value(self, value):should work with Django running with python3 (I'll use this code soon - yet not tested).
Note, though, that I'm passing
encoding='utf-8', errors='ignore'parameters to
decode()and
unicode() methods. Encoding should match your Django settings.py configuration and passing
errors='ignore'is optional (and may result in silent data loss instead of exception whith misconfigured django in rare cases).
import sys
...
def get_prep_value(self, value):
if value is None:
return value
if sys.version_info[0] >= 3:
if isinstance(out_data, type(b'')):
return value.decode(encoding='utf-8', errors='ignore')
else:
if isinstance(out_data, type(b'')):
return unicode(value, encoding='utf-8', errors='ignore')
return str(value)
...
add a comment |
With my current reputation I have no ability to comment, so I choose answer referencing comments for sample code in reply by Prashant Gaur (thanks, Gaur - this was helpful!) - his sample is for python2, since python3 has no
unicodemethod.
The replacement below for function
get_prep_value(self, value):should work with Django running with python3 (I'll use this code soon - yet not tested).
Note, though, that I'm passing
encoding='utf-8', errors='ignore'parameters to
decode()and
unicode() methods. Encoding should match your Django settings.py configuration and passing
errors='ignore'is optional (and may result in silent data loss instead of exception whith misconfigured django in rare cases).
import sys
...
def get_prep_value(self, value):
if value is None:
return value
if sys.version_info[0] >= 3:
if isinstance(out_data, type(b'')):
return value.decode(encoding='utf-8', errors='ignore')
else:
if isinstance(out_data, type(b'')):
return unicode(value, encoding='utf-8', errors='ignore')
return str(value)
...
With my current reputation I have no ability to comment, so I choose answer referencing comments for sample code in reply by Prashant Gaur (thanks, Gaur - this was helpful!) - his sample is for python2, since python3 has no
unicodemethod.
The replacement below for function
get_prep_value(self, value):should work with Django running with python3 (I'll use this code soon - yet not tested).
Note, though, that I'm passing
encoding='utf-8', errors='ignore'parameters to
decode()and
unicode() methods. Encoding should match your Django settings.py configuration and passing
errors='ignore'is optional (and may result in silent data loss instead of exception whith misconfigured django in rare cases).
import sys
...
def get_prep_value(self, value):
if value is None:
return value
if sys.version_info[0] >= 3:
if isinstance(out_data, type(b'')):
return value.decode(encoding='utf-8', errors='ignore')
else:
if isinstance(out_data, type(b'')):
return unicode(value, encoding='utf-8', errors='ignore')
return str(value)
...
edited Jul 26 '18 at 18:38
answered Jul 26 '18 at 18:31
Oleg ArtemevOleg Artemev
13
13
add a comment |
add a comment |
It's quite an old topic, but since it is returned when searching for "django list field" I'll share the custom django list field code I modified to work with Python 3 and Django 2. It supports the admin interface now and not uses eval (which is a huge security breach in Prashant Gaur's code).
from django.db import models
from typing import Iterable
class ListField(models.TextField):
"""
A custom Django field to represent lists as comma separated strings
"""
def __init__(self, *args, **kwargs):
self.token = kwargs.pop('token', ',')
super().__init__(*args, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
kwargs['token'] = self.token
return name, path, args, kwargs
def to_python(self, value):
class SubList(list):
def __init__(self, token, *args):
self.token = token
super().__init__(*args)
def __str__(self):
return self.token.join(self)
if isinstance(value, list):
return value
if value is None:
return SubList(self.token)
return SubList(self.token, value.split(self.token))
def from_db_value(self, value, expression, connection):
return self.to_python(value)
def get_prep_value(self, value):
if not value:
return
assert(isinstance(value, Iterable))
return self.token.join(value)
def value_to_string(self, obj):
value = self.value_from_object(obj)
return self.get_prep_value(value)
add a comment |
It's quite an old topic, but since it is returned when searching for "django list field" I'll share the custom django list field code I modified to work with Python 3 and Django 2. It supports the admin interface now and not uses eval (which is a huge security breach in Prashant Gaur's code).
from django.db import models
from typing import Iterable
class ListField(models.TextField):
"""
A custom Django field to represent lists as comma separated strings
"""
def __init__(self, *args, **kwargs):
self.token = kwargs.pop('token', ',')
super().__init__(*args, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
kwargs['token'] = self.token
return name, path, args, kwargs
def to_python(self, value):
class SubList(list):
def __init__(self, token, *args):
self.token = token
super().__init__(*args)
def __str__(self):
return self.token.join(self)
if isinstance(value, list):
return value
if value is None:
return SubList(self.token)
return SubList(self.token, value.split(self.token))
def from_db_value(self, value, expression, connection):
return self.to_python(value)
def get_prep_value(self, value):
if not value:
return
assert(isinstance(value, Iterable))
return self.token.join(value)
def value_to_string(self, obj):
value = self.value_from_object(obj)
return self.get_prep_value(value)
add a comment |
It's quite an old topic, but since it is returned when searching for "django list field" I'll share the custom django list field code I modified to work with Python 3 and Django 2. It supports the admin interface now and not uses eval (which is a huge security breach in Prashant Gaur's code).
from django.db import models
from typing import Iterable
class ListField(models.TextField):
"""
A custom Django field to represent lists as comma separated strings
"""
def __init__(self, *args, **kwargs):
self.token = kwargs.pop('token', ',')
super().__init__(*args, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
kwargs['token'] = self.token
return name, path, args, kwargs
def to_python(self, value):
class SubList(list):
def __init__(self, token, *args):
self.token = token
super().__init__(*args)
def __str__(self):
return self.token.join(self)
if isinstance(value, list):
return value
if value is None:
return SubList(self.token)
return SubList(self.token, value.split(self.token))
def from_db_value(self, value, expression, connection):
return self.to_python(value)
def get_prep_value(self, value):
if not value:
return
assert(isinstance(value, Iterable))
return self.token.join(value)
def value_to_string(self, obj):
value = self.value_from_object(obj)
return self.get_prep_value(value)
It's quite an old topic, but since it is returned when searching for "django list field" I'll share the custom django list field code I modified to work with Python 3 and Django 2. It supports the admin interface now and not uses eval (which is a huge security breach in Prashant Gaur's code).
from django.db import models
from typing import Iterable
class ListField(models.TextField):
"""
A custom Django field to represent lists as comma separated strings
"""
def __init__(self, *args, **kwargs):
self.token = kwargs.pop('token', ',')
super().__init__(*args, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
kwargs['token'] = self.token
return name, path, args, kwargs
def to_python(self, value):
class SubList(list):
def __init__(self, token, *args):
self.token = token
super().__init__(*args)
def __str__(self):
return self.token.join(self)
if isinstance(value, list):
return value
if value is None:
return SubList(self.token)
return SubList(self.token, value.split(self.token))
def from_db_value(self, value, expression, connection):
return self.to_python(value)
def get_prep_value(self, value):
if not value:
return
assert(isinstance(value, Iterable))
return self.token.join(value)
def value_to_string(self, obj):
value = self.value_from_object(obj)
return self.get_prep_value(value)
answered Nov 20 '18 at 0:48
YaroslavYaroslav
1,105812
1,105812
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f22340258%2fdjango-list-field-in-model%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Which database are you using?
– erthalion
Mar 12 '14 at 4:25