Flag Field Type Feature Request

95 views
Skip to first unread message

Paul Kenjora

unread,
Nov 1, 2013, 3:50:47 PM11/1/13
to django-d...@googlegroups.com
Hi,

  I'd like to propose a new field type I've used on several projects.  Its a list of boolean flags all in one field.  It replaces the need for many Boolean fields and has the same basic DB lookup capabilities.  This is fully Admin compatible and Database agnostic.

  Here is the full code, I'm sure it could use some minor tweaks.

from django.db import models
from django.forms import MultipleChoiceField, CheckboxSelectMultiple

class FlagField(models.Field):

  description = "A set of flags."
  __metaclass__ = models.SubfieldBase

  def __init__(self, flags, *args, **kwargs):
    self.flags = flags
    super(FlagField, self).__init__(*args, **kwargs)

  def db_type(self, connection):
    return 'char(%s)' % len(self.flags)

  def to_python(self, value):
    if isinstance(value, list) or isinstance(value, set):
      flagged = set(value)
    else:
      flagged = set()
      for i,c in enumerate(value):
        if c == '1' and i < len(self.flags): flagged.add(self.flags[i])
    return flagged

  def get_db_prep_value(self, value, connection, prepared=False):
    return ''.join(map(lambda flag: '1' if flag in value else '0', self.flags))

  def formfield(self, **kwargs):
    defaults = {'form_class': MultipleChoiceField, 'widget':CheckboxSelectMultiple, 'choices':map(lambda f: (f, f), self.flags)}
    defaults.update(kwargs)
    return super(FlagField, self).formfield(**defaults)

Regards,                                                                                  

--
- Paul Kenjora
- 602-214-7285

Michael Manfre

unread,
Nov 1, 2013, 4:22:44 PM11/1/13
to django-d...@googlegroups.com
Storing bits as a string is not an efficient use of space and is slower to query. Any reason why you are not using the bit datatype with a length? E.g. 'bit(%s)' % len(self.flags)

Regards,
Michael Manfre


--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To post to this group, send email to django-d...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAEH8JE3356WqGVgF9fNxYhTXs%2BVDNVm-iryTBCoFoB6bXcxOgA%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.

Russell Keith-Magee

unread,
Nov 1, 2013, 6:24:21 PM11/1/13
to Django Developers

Agreed - if we were going to implement this, we'd use a bit string implementation, not push it into a char field.

Yours,
Russ Magee %-)


Sergiy Kuzmenko

unread,
Nov 1, 2013, 8:53:42 PM11/1/13
to django-d...@googlegroups.com
I often found this handy too. Here's my implementation on bitbucket[1]. There are tests[2] and documentation[3]. It's something I wanted propose to Django core as well but never found time to do so. :)

In my implementation I chose to assign numeric values explicitly:

SetField(choices=((1,"pizza"),(2,"pasta"),(4,"seafood")))

instead of:

SetField(choices=("pizza","pasta","seafood"))

This is for two reasons:

1) It makes it compatible with Django's standard implementation of choices.
2) Implicit index assignment is bug prone if the order of choices changes.




Reply all
Reply to author
Forward
0 new messages