Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for null=True (and default=None) to BitField class. #14

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions bitfield/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ def __get__(self, obj, type=None):
if obj is None:
return BitFieldFlags(self.field.flags)
retval = obj.__dict__[self.field.name]
if self.field.__class__ is BitField:
# handle case where value of field is None
if not retval is None and self.field.__class__ is BitField:
# Update flags from class in case they've changed.
retval._keys = self.field.flags
return retval
Expand Down Expand Up @@ -106,7 +107,11 @@ def pre_save(self, instance, add):
def get_prep_value(self, value):
if isinstance(value, (BitHandler, Bit)):
value = value.mask
return int(value)
# handle case where value is None
if value is not None:
return int(value)
else:
return value

# def get_db_prep_save(self, value, connection):
# if isinstance(value, Bit):
Expand All @@ -133,7 +138,10 @@ def get_prep_lookup(self, lookup_type, value):
def to_python(self, value):
if isinstance(value, Bit):
value = value.mask
if not isinstance(value, BitHandler):
# handle case where value is None
if value is None:
pass
elif not isinstance(value, BitHandler):
# Regression for #1425: fix bad data that was created resulting
# in negative values for flags. Compute the value that would
# have been visible ot the application to preserve compatibility.
Expand Down
7 changes: 7 additions & 0 deletions bitfield/tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,10 @@ class CompositeBitFieldTestModel(models.Model):
'flags_2',
))

class BitFieldNullDefaultModel(models.Model):
flags = BitField(flags=(
'FLAG_0',
'FLAG_1',
'FLAG_2',
'FLAG_3',
), null=True, default=None, db_column='another_default_null_name')
30 changes: 29 additions & 1 deletion bitfield/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.test import TestCase

from bitfield import BitHandler, Bit
from bitfield.tests import BitFieldTestModel, CompositeBitFieldTestModel
from bitfield.tests import BitFieldTestModel, CompositeBitFieldTestModel, BitFieldNullDefaultModel

class BitHandlerTest(TestCase):
def test_defaults(self):
Expand Down Expand Up @@ -289,3 +289,31 @@ def test_hasattr(self):
self.assertEqual(hasattr(inst.flags, 'flag_4'),
hasattr(inst.flags_2, 'flag_4'))

class NullDefaultBitfieldTest(TestCase):
"""Null values for bitfields used to not work. This test checks to make sure they do work
now and don't break other non-null cases."""
def test_create_default_null(self):
inst = BitFieldNullDefaultModel()
# flags should be None (null) by default
self.assertIsNone(inst.flags)
inst.save()
# make sure still None (null) after save
self.assertIsNone(inst.flags)
inst = BitFieldNullDefaultModel.objects.get(pk=inst.pk)
# make sure still None (null) after being loaded back in
self.assertIsNone(inst.flags)
# make sure we can still set the flags
inst.flags = 1
self.assertEqual(type(inst.flags),BitHandler)
inst.save()
inst = BitFieldNullDefaultModel.objects.get(pk=inst.pk)
self.assertEqual(type(inst.flags),BitHandler)
self.assertTrue(inst.flags.FLAG_0.is_set)
# and that we haven't broken things
self.assertFalse(inst.flags.FLAG_1.is_set)
inst.save()
inst = BitFieldNullDefaultModel.objects.get(pk=inst.pk)
self.assertEqual(type(inst.flags),BitHandler)
self.assertTrue(inst.flags.FLAG_0.is_set)
self.assertFalse(inst.flags.FLAG_1.is_set)

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

setup(
name='django-bitfield',
version='1.5.0',
version='1.5.0.ejs',
author='DISQUS',
author_email='[email protected]',
url='http://github.com/disqus/django-bitfield',
Expand Down