Skip to content
Advertisement

Django Model method that uses data from the model

I want to generate unique codes (e.g. “DXGH”) and save it as a field in one of my models. The problem I have is that I do not know how to check against previously generated codes whenever a new object is created.

Currently my models.py looks something like this:

def code_gen():
    random_string = ''
    for _ in range(4):
        random_string += chr(random.randint(97,122))
    return random_string

class Room(models.Model):
    room_code = models.CharField(default=code_gen)
    #other fields

    def __str__(self):
        return self.room_code

    #other methods

    def code_gen_unique(self):
        #I know the code below is incorrect
        code_list = []
        for object in Room.Objects.all():
            code_list.append(object.room_code)
        while True:
            temp_code = code_gen()
            if temp_code in code_list:
                continue
            break
        return temp_code

Ideally I would set the default value of room_code to code_gen_unique, but I can’t declare code_gen_unique() before my Room class, nor after it.

I expect there is a much easier solution than I have considered, and would appreciate any help very much! Cheers


Edit

Thanks to Willem Van Onsem for correcting my understanding – declaring the uniqueness-checking function before the Model, and setting the function as the default value for the room_code field does the job.

Advertisement

Answer

You can define the default generator before you define the Room class:

def code_gen():
    random_string = ''
    for _ in range(4):
        random_string += chr(random.randint(97,122))
    return random_string

def code_gen_unique():
    code_set = set(Room.Objects.values('room_code'))
    while True:
        temp_code = code_gen()
        if temp_code not in code_set:
            return temp_code

class Room(models.Model):
    room_code = models.CharField(default=code_gen)
    
    # …

The Room identifier will be resolved to the Room class, since the method will not run when defined, but when called, and it will only be called when constructing a new Room object.

Advertisement