Login

StringListField (database field)

Author:
guettli
Posted:
May 6, 2009
Language:
Python
Version:
1.0
Score:
1 (after 1 ratings)

This django.db.models.Field stores a list of python strings in one database column.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# -*- coding: iso-8859-1 -*-
# $Id: StringListField.py 344 2009-05-06 06:57:27Z tguettler $
# $HeadURL: svn+ssh://svnserver/svn/djangotools/trunk/dbfields/StringListField.py $

# http://www.djangosnippets.org/snippets/1491/

# Django
from django.db import models
from django import forms

class StringListField(models.Field):
    u'''
    Save a list of strings in a CharField (or TextField) column.

    In the django model object the column is a list of strings.
    '''
    __metaclass__=models.SubfieldBase
    SPLIT_CHAR=u'\v'
    def __init__(self, *args, **kwargs):
        self.internal_type=kwargs.pop('internal_type', 'CharField') # or TextField
        super(StringListField, self).__init__(*args, **kwargs)

    def to_python(self, value):
        if isinstance(value, list):
            return value
        if value is None:
            return []
        return value.split(self.SPLIT_CHAR)

    def get_internal_type(self):
        return self.internal_type

    def get_db_prep_lookup(self, lookup_type, value):
        # SQL WHERE
        raise NotImplementedError()

    def get_db_prep_save(self, value):
        return self.SPLIT_CHAR.join(value)

    def formfield(self, **kwargs):
        assert not kwargs, kwargs
        return forms.MultipleChoiceField(choices=self.choices)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

dharris (on October 28, 2009):

I've modified this locally to handle saving and loading empty values better.

In get_db_prep_save (line 37-38), I added:

if not value:
    return None

without this, an empty string was saved -- I prefer a NULL in the db.

Line 26-27, I changed this to

if value is None or value == '':
    return []

#

fylb (on August 30, 2012):

When using choices, in order to be able to use the widget, I had to add a validate method:

def validate(self, value, model_instance):
    """
    Validates value and throws ValidationError. Subclasses should override
    this to provide validation logic.
    """
    if not self.editable:
        # Skip validation for non-editable fields.
        return
    if self._choices and value:
        l = value
        if type(value) != list:
            l = [ value ]
        for v in value:
            for option_key, option_value in self.choices:
                if isinstance(option_value, (list, tuple)):
                    # This is an optgroup, so look inside the group for options.
                    for optgroup_key, optgroup_value in option_value:
                        if v == optgroup_key:
                            return
                elif v == option_key:
                    return
            raise exceptions.ValidationError(self.error_messages['invalid_choice'] % v)

    if value is None and not self.null:
        raise exceptions.ValidationError(self.error_messages['null'])

    if not self.blank and value in validators.EMPTY_VALUES:
        raise exceptions.ValidationError(self.error_messages['blank'])

#

Please login first before commenting.