Field with values generated by combining auto field with given Django symbols
There are many ways to answer your question. It really depends on the purpose of this field and when you want the code to be autogenerated (before or after saving the record).
In the following code, I define a Charfield that stores codes with a fixed part ("KAM") and an incremental ("001", "002", ...), neither of these parts already defined elsewhere when the object is saved , field code, if empty, is filled in gradually.
class MyModel(models.Model):
code = models.CharField(blank=True, default='')
def save(self, force_insert=False, force_update=False):
if self.code == "":
existing_codes = MyModel.objects.all().order_by('-code')
if existing_codes.count() > 0:
new_code = int(existing_codes[0].code[1:]) + 1
else:
new_code = 0
self.code = 'KAM%03d' % new_code
super(MyModel, self).save(force_insert, force_update)
If you want to concatenate a string into an autoincrement field, the code is a little less complicated:
class MyModel(models.Model):
id = models.AutoField(primary_key=True)
code = models.CharField(blank=True, default='')
def save(self, force_insert=False, force_update=False):
self.code = 'KAM%08d' % self.id
super(MyModel, self).save(force_insert, force_update)
If you want the code to be defined before saving the entry , you can use this approach:
class MyModel(models.Model):
code = models.CharField(blank=True, default=new_code)
@property
def new_code(self):
existing_codes = MyModel.objects.all().order_by('-code')
if existing_codes.count() > 0:
new_code = int(existing_codes[0].code[1:]) + 1
else:
new_code = 0
return 'KAM%03d' % new_code
but please note that this approach can generate duplicate values if two objects are created before the first is saved, so I discourage you from using that approach.
other approaches might use signals, triggers, etc. These are just a few of the many.
for example, if you don't need to execute queries based on the "Charfield" field, I suggest you an alternative approach:
class MyModel(models.Model):
# ... your fields here
def my_code(self):
return 'KAM%08d'%self.pk # please note that I've added more padding zeroes
it can be called from your templates like this:
{{obj.my_code}}
where obj is an instance of MyModel
if you also need to change the start part for some records (the "KAM" part), the "define on save" approach is the way to go.
source to share