Login

StringListField (database field)

Author:
guettli
Posted:
May 6, 2009
Language:
Python
Version:
1.0
Tags:
field
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

Comments

dharris (on October 28, 2009):
<p>I've modified this locally to handle saving and loading empty values better.</p> <p>In get_db_prep_save (line 37-38), I added:</p> <pre>if not value: return None </pre> <p>without this, an empty string was saved -- I prefer a NULL in the db.</p> <p>Line 26-27, I changed this to </p> <pre>if value is None or value == '': return [] </pre>

#

fylb (on August 30, 2012):
<p>When using choices, in order to be able to use the widget, I had to add a validate method:</p> <pre>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']) </pre>

#

Please login first before commenting.