Field with values ​​generated by combining auto field with given Django symbols

I want to have Django CharField

in my models whose values ​​will be generated as by combining a fixed value and an autogenerated value value, for example, value 1: KAM001, Value2: KAM002 ...

I am sure I can achieve this.

+3


source to share


1 answer


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.

+2


source







All Articles