Skip to content

Commit

Permalink
Merge pull request #684 from dpetzold/random-char-field-followup
Browse files Browse the repository at this point in the history
Random char field followup
  • Loading branch information
trbs committed Jun 12, 2015
2 parents c72d0e3 + d4db4ba commit 3266a6d
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 11 deletions.
22 changes: 14 additions & 8 deletions django_extensions/db/fields/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""
Django Extensions additional model fields
"""
import random
import re
import six
import string
Expand All @@ -20,8 +19,9 @@
HAS_SHORT_UUID = False

from django.core.exceptions import ImproperlyConfigured
from django.template.defaultfilters import slugify
from django.db.models import DateTimeField, CharField, SlugField
from django.utils.crypto import get_random_string
from django.template.defaultfilters import slugify

try:
from django.utils.timezone import now as datetime_now
Expand All @@ -37,7 +37,6 @@


MAX_UNIQUE_QUERY_ATTEMPTS = 100
random_sample = random.SystemRandom().sample


class UniqueFieldMixin(object):
Expand Down Expand Up @@ -214,7 +213,7 @@ def deconstruct(self):
class RandomCharField(UniqueFieldMixin, CharField):
""" RandomCharField
By default, sets editable=False, blank=True.
By default, sets editable=False, blank=True, db_index=False.
Required arguments:
Expand All @@ -223,6 +222,9 @@ class RandomCharField(UniqueFieldMixin, CharField):
Optional arguments:
db_index
If set to True, duplicate entries are not allowed (default: False)
lowercase
If set to True, lowercase the alpha characters (default: False)
Expand Down Expand Up @@ -253,15 +255,15 @@ def __init__(self, *args, **kwargs):
self.include_punctuation = kwargs.pop('include_punctuation', False)
self.check_is_bool('include_punctuation')

# Set db_index=True unless it's been set manually.
# Set db_index=False unless it's been set manually.
if 'db_index' not in kwargs:
kwargs['db_index'] = True
kwargs['db_index'] = False

super(RandomCharField, self).__init__(*args, **kwargs)

def random_char_generator(self, chars):
for i in range(100):
yield ''.join(random_sample(chars, self.length))
yield ''.join(get_random_string(self.length, chars))
raise RuntimeError('max random character attempts exceeded (%s)' %
MAX_UNIQUE_QUERY_ATTEMPTS)

Expand All @@ -282,10 +284,14 @@ def pre_save(self, model_instance, add):
if self.include_punctuation:
population += string.punctuation

random_chars = self.random_char_generator(population)
if not self.db_index:
return random_chars

return super(RandomCharField, self).find_unique(
model_instance,
model_instance._meta.get_field(self.attname),
self.random_char_generator(population),
random_chars,
)

def internal_type(self):
Expand Down
2 changes: 1 addition & 1 deletion docs/field_extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Current Database Model Field Extensions
a length of 8 thats yields 3.4 million possible combinations. A 12
character field would yield about 2 billion. Below are some examples::

>>> RandomCharField(length=8)
>>> RandomCharField(length=8, db_index=True)
BVm9GEaE

>>> RandomCharField(length=4, include_alpha=False)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_randomchar_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def testRandomCharTestModelDuplicate(self):
assert m.random_char_field == 'aaa'

def testRandomCharTestModelAsserts(self):
with mock.patch('django_extensions.db.fields.random_sample') as mock_sample:
with mock.patch('django_extensions.db.fields.get_random_string') as mock_sample:
mock_sample.return_value = 'aaa'
m = RandomCharTestModel()
m.save()
Expand Down
2 changes: 1 addition & 1 deletion tests/testapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ class Meta:


class RandomCharTestModel(models.Model):
random_char_field = RandomCharField(length=8)
random_char_field = RandomCharField(length=8, db_index=True)

class Meta:
app_label = 'django_extensions'
Expand Down

0 comments on commit 3266a6d

Please sign in to comment.