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.
CodePudding user response:
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.