Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Random char field followup #684

Merged
merged 2 commits into from
Jun 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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