Skip to content

Instantly share code, notes, and snippets.

@barbuza
Created May 11, 2011 10:43
Show Gist options
  • Save barbuza/966267 to your computer and use it in GitHub Desktop.
Save barbuza/966267 to your computer and use it in GitHub Desktop.
BitOptionsField holds a short list of predefined options in a single integer field
# -*- coding: utf-8 -*-
from django.db import models
from django.core import exceptions
__all__ = ("BitOptionsField", )
class BitOptionsField(models.Field):
"""
BitOptionsField holds a short list of predefined options
in a single integer field.
'options' argument is required, it should provide predefined
list of options
'default' argument is optional, it can provide default list
of options
"""
__metaclass__ = models.SubfieldBase
def __init__(self, *args, **kwargs):
if "options" not in kwargs:
raise RuntimeError("options param is required for BitOptionsField")
self.options = kwargs.pop("options")
if "default" in kwargs:
if not isinstance(kwargs["default"], int):
kwargs["default"] = self._encode_options(kwargs["default"])
else:
kwargs["default"] = 0
super(BitOptionsField, self).__init__(*args, **kwargs)
def get_internal_type(self):
return "IntegerField"
def to_python(self, value):
if type(value) in (int, long):
return self._decode_options(value)
return value
def get_db_prep_value(self, value, connection=None, prepared=False):
if type(value) in (int, long):
return value
return self._encode_options(value)
def _decode_options(self, value):
opts = []
for index, option in enumerate(self.options):
if value & (1 << index):
opts.append(option)
return opts
def _encode_options(self, value):
int_val = 0
for option in value:
if option not in self.options:
raise exceptions.ValidationError("%s is not valid option" \
% option)
int_val += (1 << self.options.index(option))
return int_val
def south_field_triple(self):
from south.modelsinspector import introspector
field_class = self.__class__.__module__ + "." + self.__class__.__name__
args, kwargs = introspector(self)
kwargs["options"] = []
return (field_class, args, kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment