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. Self-referencing Foreign Key Infinite Loop by minarets 6 years, 7 months ago
  2. Model inheritance with content type by crucialfelix 5 years, 7 months ago
  3. jstree integration to django admin by pawnhearts 4 years, 3 months ago
  4. Limit queryset to objects related to parent in ManyToMany fields within admin inlines by DrMeers 3 years, 11 months ago
  5. Hierarchical page slugs by baumer1122 6 years, 8 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?)