Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - Boolean field with Single True

I want a boolean field that only allows for ONE of them to be True based on a foreign key (User). I am now sure how to word this or really search for it, but I was able to get a simple implementation working, but I do not like it. It feels clunky and wrong. Anyways, the best way to get what I mean is you see it, here you go:

class MyModel(models.Model):
    owner = models.ForeignKey(User)
    _is_main = models.BooleanField(default=False)

    def __get_is_main(self):
        return self._is_main

    def __set_is_main(self, is_main):
        if (is_main):
            active_keys = API_Key.objects.filter(_is_main=True, owner=self.owner)
            if (len(active_keys) == 1 and self in active_keys):
                return
            else:
                for key in active_keys:
                    if (key.is_main):
                        key.is_main = False
                        key.save()
        self._is_main = is_main
        self.save()

    is_main = property(__get_is_main, __set_is_main)

I only want is_main to be True for each owner ONCE, no more then once. These are for API keys. So the owner can have many API Keys but only one is set to the main one. This is the only way I could figure out how to implement this. Anyone have a better way to do this? I am using MySQL if it matters.

like image 473
angellusmortis Avatar asked Nov 10 '22 15:11

angellusmortis


1 Answers

Maybe you don't need that field but have a singleton pointing to a main key. Something along these lines:

class Key(models.Model):
    owner = models.ForeignKey(User)

    @property
    def is_main(self):
        return hasattr(self, 'is_main')

    def set_main(self):
        # update MainKey instance here


class MainKey(models.Model):
    key = models.ForeignKey(Key, related_name='is_main')

    def save(self, *args, **kwargs):
        self.id = 1
        super(MainKey, self).save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        pass
like image 184
Dmitry Mukhin Avatar answered Nov 15 '22 07:11

Dmitry Mukhin