Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

limit one record to be default in django model

Tags:

django

What is the best way to limit only one record to be default in django

I have a model where i have a flag for default

class BOMVersion(models.Model): 
    name = models.CharField(max_length=200,null=True, blank=True)
    material =  models.ForeignKey(Material)   
    is_default = models.BooleanField(default=False)

I want to have only one value to be default for the same material but this material can have a lot of non default ones.

like image 582
Ilya Bibik Avatar asked Nov 02 '25 05:11

Ilya Bibik


1 Answers

It was odd that this question was not addressed more often. If I have a default record, I want to record that in the class as a member variable. And to determine if an instance is the default, I want to compare the class default member variable with the instance id. Unfortunately I could not figure out how to access class variables and instance variables nicely in the same class function in Python (may be someone can comment), but this does not require to hit the database for a default or store a bunch of records pointing to a default. Just one member variable in the class.

After I wrote this, I realized every time the application is restarted, default is reset to None, so you will have to store this in a database. I have updated my answer accordingly. However, checking that the member variable is not null, and only hitting the database if it is would reduce hits here. The model I used was:

class RecordOfInterest(models.Model):
"""
Record Records of interest here. Stores ID, and identifying character
"""
# asume maximum 64 character limit for the model.
model_name = models.CharField(max_length=64, unique=True)
record_no = models.IntegerField()
human_ident = models.CharField(max_length=64, help_text='How is this of interest') 
# Id it as default, deposit, ... Don't bother indexing, as there will only be a few

def __unicode__(self):
    return u'Model %s record %d for %s' % (self.model_name, self.record_no, self.human_ident)

class Meta:
    unique_together = ('model_name', 'human_ident')

class Product(models.Model):
    """
    Allow one product record to be the default using "Product.default = prod_instance"
    check default with "Product.is_default(prod_instance)"
    """
    default = None # set this to id of the default record
    cart_heading = models.CharField(max_length=64, blank=True)
    country = CountryField()
    pricing = models.ForeignKey(
        'Price', blank=True, null=True, related_name='visas', on_delete=models.SET_NULL)

    @classmethod
    def is_default(cls, obj):
        if cls.default_no == None:
            try:
                cls.default_no = RecordOfInterest.objects.get(model_name=cls.__name__, human_ident='default')
            except RecordOfInterest.DoesNotExist: 
                default_no = None
        return cls.default_no == obj.id

@classmethod
def set_default(cls, obj):
    try:
        default_rec = RecordOfInterest.objects.get(model_name=cls.__name__, human_ident='default')
    except RecordOfInterest.DoesNotExist:
        RecordOfInterest.objects.create(model_name=cls.__name__, record_no=obj.id, human_ident='default')
    else:
        if default_rec.record_no != obj.id:
            default_rec.record_no = obj.id
            default_rec.save()
    cls.default_no = obj.id
    return
like image 55
MagicLAMP Avatar answered Nov 04 '25 05:11

MagicLAMP



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!