Django: List field in model?












54















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?










share|improve this question




















  • 1





    Which database are you using?

    – erthalion
    Mar 12 '14 at 4:25
















54















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?










share|improve this question




















  • 1





    Which database are you using?

    – erthalion
    Mar 12 '14 at 4:25














54












54








54


20






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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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














  • 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












9 Answers
9






active

oldest

votes


















76














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.






share|improve this answer





















  • 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 new ArrayField field you can use. See answer below.

    – madmanick
    Apr 17 '17 at 2:35



















20














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).






share|improve this answer































    16














    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,
    )





    share|improve this answer





















    • 1





      Thanks! Looks like its postgres specific but a great one!

      – Anupam
      Jul 13 '17 at 4:48



















    15














    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]]
    >>>





    share|improve this answer


























    • 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



















    7














    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.






    share|improve this answer































      1














      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.






      share|improve this answer



















      • 1





        Note that this is deprecated as of Django 1.9 per the link in the article.

        – phoenix
        Apr 11 '16 at 0:50



















      0














      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.






      share|improve this answer































        0














        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


        unicode
        method.

        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)
        ...









        share|improve this answer

































          0














          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)





          share|improve this answer























            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
            });


            }
            });














            draft saved

            draft discarded


















            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









            76














            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.






            share|improve this answer





















            • 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 new ArrayField field you can use. See answer below.

              – madmanick
              Apr 17 '17 at 2:35
















            76














            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.






            share|improve this answer





















            • 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 new ArrayField field you can use. See answer below.

              – madmanick
              Apr 17 '17 at 2:35














            76












            76








            76







            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.






            share|improve this answer















            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            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 new ArrayField field you can use. See answer below.

              – madmanick
              Apr 17 '17 at 2:35














            • 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 new ArrayField 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













            20














            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).






            share|improve this answer




























              20














              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).






              share|improve this answer


























                20












                20








                20







                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).






                share|improve this answer













                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).







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jun 13 '15 at 16:01









                RisadinhaRisadinha

                9,25115562




                9,25115562























                    16














                    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,
                    )





                    share|improve this answer





















                    • 1





                      Thanks! Looks like its postgres specific but a great one!

                      – Anupam
                      Jul 13 '17 at 4:48
















                    16














                    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,
                    )





                    share|improve this answer





















                    • 1





                      Thanks! Looks like its postgres specific but a great one!

                      – Anupam
                      Jul 13 '17 at 4:48














                    16












                    16








                    16







                    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,
                    )





                    share|improve this answer















                    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,
                    )






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    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














                    • 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











                    15














                    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]]
                    >>>





                    share|improve this answer


























                    • 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
















                    15














                    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]]
                    >>>





                    share|improve this answer


























                    • 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














                    15












                    15








                    15







                    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]]
                    >>>





                    share|improve this answer















                    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]]
                    >>>






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    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



















                    • 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











                    7














                    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.






                    share|improve this answer




























                      7














                      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.






                      share|improve this answer


























                        7












                        7








                        7







                        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.






                        share|improve this answer













                        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.







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Mar 12 '14 at 17:49









                        alecxealecxe

                        327k71644868




                        327k71644868























                            1














                            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.






                            share|improve this answer



















                            • 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














                            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.






                            share|improve this answer



















                            • 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








                            1







                            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.






                            share|improve this answer













                            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.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            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














                            • 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











                            0














                            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.






                            share|improve this answer




























                              0














                              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.






                              share|improve this answer


























                                0












                                0








                                0







                                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.






                                share|improve this answer













                                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.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Mar 25 '16 at 13:23









                                speedplanespeedplane

                                9,243964109




                                9,243964109























                                    0














                                    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


                                    unicode
                                    method.

                                    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)
                                    ...









                                    share|improve this answer






























                                      0














                                      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


                                      unicode
                                      method.

                                      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)
                                      ...









                                      share|improve this answer




























                                        0












                                        0








                                        0







                                        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


                                        unicode
                                        method.

                                        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)
                                        ...









                                        share|improve this answer















                                        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


                                        unicode
                                        method.

                                        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)
                                        ...










                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited Jul 26 '18 at 18:38

























                                        answered Jul 26 '18 at 18:31









                                        Oleg ArtemevOleg Artemev

                                        13




                                        13























                                            0














                                            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)





                                            share|improve this answer




























                                              0














                                              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)





                                              share|improve this answer


























                                                0












                                                0








                                                0







                                                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)





                                                share|improve this answer













                                                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)






                                                share|improve this answer












                                                share|improve this answer



                                                share|improve this answer










                                                answered Nov 20 '18 at 0:48









                                                YaroslavYaroslav

                                                1,105812




                                                1,105812






























                                                    draft saved

                                                    draft discarded




















































                                                    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.




                                                    draft saved


                                                    draft discarded














                                                    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





















































                                                    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







                                                    這個網誌中的熱門文章

                                                    Tangent Lines Diagram Along Smooth Curve

                                                    Yusuf al-Mu'taman ibn Hud

                                                    Zucchini