Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Imports
3from string import ascii_letters as letters
4from django.core.exceptions import FieldError
5from django.db import models
6from django.utils.crypto import get_random_string
7from django.utils.translation import ugettext_lazy as _
9# Exports
11__all__ = (
12 "RandomCharField",
13)
15# Fields
18class RandomCharField(models.CharField):
19 """Generates random characters when the field is saved.
21 **Possible Uses**
23 - Create a confirmation token for password resets or account creation.
24 - Assist with SPAM prevention.
26 """
27 description = _("Generates random characters when the field is saved.")
29 def __init__(self, *args, **kwargs):
31 # Set defaults.
32 kwargs.setdefault('blank', True)
33 kwargs.setdefault('max_length', 62)
35 # Initialize and letter errors bubble up before we continue.
36 super().__init__(*args, **kwargs)
38 # Validate max_length.
39 length = kwargs['max_length']
40 if length > 62:
41 message = "max_length cannot be greater than 62 for RandomCharField."
42 raise FieldError(message)
44 # Set the list of available characters based on max_length.
45 characters = letters + '0123456789'
46 self.characters = characters[:length]
48 def formfield(self, **kwargs):
49 kwargs['disabled'] = True
50 return super().formfield(**kwargs)
52 def generate_text(self):
53 """Generate the random text."""
54 return get_random_string(self.max_length, self.characters)
56 def pre_save(self, model_instance, add):
57 """Set the value of the field to a random string of text."""
58 # if not add and getattr(model_instance, self.attname) != '':
59 # return getattr(model_instance, self.attname)
60 #
61 # value = self.generate_text()
62 # setattr(model_instance, self.attname, value)
63 #
64 # return value
66 # There is no need to generate a random string twice.
67 value = getattr(model_instance, self.attname)
68 # print("existing value", model_instance, self.attname, value)
69 if not value:
70 value = self.generate_text()
71 setattr(model_instance, self.attname, value)
73 return value