Exclusive boolean field

 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
43
44
45
46
47
48
49
50
from django.db.models.signals import post_save

"""
an Exclusive Boolean Field means that only one row in the model table
can have that field True at a time...

if you supply names in 'with_fields' then only one row in the model table
where those additional fields match the instance being saved can have
their exclusive boolean fields True at the same time.
"""
def exclusive_boolean_handler(sender, instance, created, **kwargs):
    eb_fields = getattr(sender, '_exclusive_boolean_fields', [])
    with_fields = getattr(sender, '_exclusive_boolean_with_fields', [])
    uargs = {}
    for field in eb_fields:
        ifield = getattr(instance, field)
        if ifield == True:
            uargs.update({field:False})
    fargs = {}
    for field in with_fields:
        ifield = getattr(instance, field)
        fargs.update({field:ifield})
    sender.objects.filter(**fargs).exclude(pk=instance.pk).update(**uargs)

def exclusive_boolean_fields(model, eb_fields=[], with_fields=[]):
    setattr(model, '_exclusive_boolean_fields', eb_fields)
    setattr(model, '_exclusive_boolean_with_fields', with_fields)
    post_save.connect(exclusive_boolean_handler, sender=model)


"""
Example usage:
"""
class Address(models.Model):
    account = models.ForeignKey(Account, related_name='addresses')
    default = models.BooleanField(default=False)
    
    country = CountryField()
    postcode = models.CharField(max_length=16)
    line1 = models.CharField(max_length=128)
    line2 = models.CharField(max_length=128, blank=True, null=True)
    line3 = models.CharField(max_length=128, blank=True, null=True)
    
exclusive_boolean_fields(Address, ('default',), ('account',))

"""
i.e.
if you set the 'default' field to True on an instance, then it will
be set False on all the other rows with the same 'account' value
"""

More like this

  1. django-mptt enabled FilteredSelectMultiple m2m widget by anentropic 3 years, 7 months ago
  2. Filtering foreignkey fields in django admin by forgems 4 years ago
  3. Create permissions for proxy models by charettes 1 year, 4 months ago
  4. Limit ForeignKey filter values to those that have a relationship with current model by overclocked 2 years, 7 months ago
  5. True Unique Boolean Decorator by kunitoki 1 year, 4 months ago

Comments

diverman (on December 8, 2009):

Nice. Better for this purpose will be theoretical TrueNoneField (modification of NullBooleanField that stores only True and None values) and unique_together with another field. Or improve data model to go around this...

#

anentropic (on October 25, 2011):

that's a nice idea and wouldn't be impossible...

#

(Forgotten your password?)