Generate a random alphanumeric string as a primary key for a model

前端 未结 3 1941
Happy的楠姐
Happy的楠姐 2021-02-03 12:28

I would like a model to generate automatically a random alphanumeric string as its primary key when I create a new instance of it.

example:

from django.d         


        
3条回答
  •  挽巷
    挽巷 (楼主)
    2021-02-03 12:43

    Here's how I would do it without making the field a primary key:

    from django.db import IntegrityError
    
    class MyTemporaryObject(models.Model):
        auto_pseudoid = models.CharField(max_length=16, blank=True, editable=False, unique=True)
        # add index=True if you plan to look objects up by it
        # blank=True is so you can validate objects before saving - the save method will ensure that it gets a value
    
        # other fields as desired
    
        def save(self, *args, **kwargs):
            if not self.auto_pseudoid:
                self.auto_pseudoid = generate_random_alphanumeric(16)
                # using your function as above or anything else
            success = False
            failures = 0
            while not success:
                try:
                    super(MyTemporaryObject, self).save(*args, **kwargs)
                except IntegrityError:
                     failures += 1
                     if failures > 5: # or some other arbitrary cutoff point at which things are clearly wrong
                         raise
                     else:
                         # looks like a collision, try another random value
                         self.auto_pseudoid = generate_random_alphanumeric(16)
                else:
                     success = True
    

    Two problems that this avoids, compared to using the field as the primary key are that:

    1) Django's built in relationship fields require integer keys

    2) Django uses the presence of the primary key in the database as a sign that save should update an existing record rather than insert a new one. This means if you do get a collision in your primary key field, it'll silently overwrite whatever else used to be in the row.

提交回复
热议问题