0

I am trying to get a base 36 string to use in my URLs. I have written a function that converts a number to base 36, using letters to represent digits higher than 9. I am trying to find a good way to set the default value of a character field equal to this function, but I am not sure how to get the Django default primary key value into it. Any ideas?

I would think I could just put something like this into my model, but it does not work:

base_36 = models.TextField(default=convert_base(id, 36))

user3234251
  • 57
  • 1
  • 8

2 Answers2

1

You could either:

  1. Override your model's save() method:

    class YourModel(models.Model):
    
        base_36 = models.TextField()
    
        def save(self, *args, **kwargs):
            # will assign a value to pk
            super(YourModel, self).save(*args, **kwargs)
            # convert the pk to base 36 and save it in our field
            self.base_36 = convert_base(self.pk, 36)
            self.save()
    
  2. Turn your base_36 field into a property:

    class YourModel(models.Model):
    
        @property
        def base_36(self):
            return convert_base(self.pk,36)
    
    # can call a property just like a field:
    # print YourModel.objects.get(pk=1).base_36
    
Community
  • 1
  • 1
pcoronel
  • 3,833
  • 22
  • 25
0

If I understand correctly you want to use a CharField as a primary key and need to redefine the way django generates its value for new objects.

I think that you would complicate your life if you proceed in that way. Instead you can use base36 identifiers only in URLs and let your view translate them into the integer corresponding to the usual primary key, as in:

def my_view(request,base32_id):
   pk = base32_to_int(base32_id)
   obj = Model.objects.get(pk=pk)
   ...
Emanuele Paolini
  • 9,912
  • 3
  • 38
  • 64
  • Hmm, I was thinking this might be the better solution but was not sure if doing all this in my views would be better than accessing the string from the database. You are probably right. I will try this out and likely mark correct in a minute. – user3234251 May 13 '14 at 16:44
  • I guess I was hoping not so much to change the primary key as create a secondary field that held this string. – user3234251 May 13 '14 at 16:46
  • I ended up using a mix of your answer and the other actually. I used the @property to print the values in my templates, and then used the standard python int(num, base) function to find the right object in my view. – user3234251 May 17 '14 at 14:25