From 38f8932e7413cde486b4f4dd20d81437a67f9b2b Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:32:56 +0100 Subject: [PATCH 01/24] UUID model added --- model_utils/models.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/model_utils/models.py b/model_utils/models.py index 2f21695..0cfafe6 100644 --- a/model_utils/models.py +++ b/model_utils/models.py @@ -1,5 +1,8 @@ from __future__ import unicode_literals +from model_utils.managers import QueryManager, SoftDeletableManager +from model_utils.fields import AutoCreatedField, AutoLastModifiedField, StatusField, MonitorField, UUIDField + import django from django.core.exceptions import ImproperlyConfigured from django.db import models @@ -10,10 +13,6 @@ if django.VERSION >= (1, 9, 0): else: from django.utils.timezone import now -from model_utils.managers import QueryManager, SoftDeletableManager -from model_utils.fields import AutoCreatedField, AutoLastModifiedField, \ - StatusField, MonitorField - class TimeStampedModel(models.Model): """ @@ -135,3 +134,18 @@ class SoftDeletableModel(models.Model): self.save(using=using) else: return super(SoftDeletableModel, self).delete(using=using, *args, **kwargs) + + +class UUIDModel(models.Model): + """ + This abstract base class provides id field on any model that inherits from it + which will be the primary key. + """ + id = UUIDField( + primary_key=True, + version=4, + editable=False, + ) + + class Meta: + abstract = True From ca752948835039bea5a86215fd478beb58df8ab8 Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:33:06 +0100 Subject: [PATCH 02/24] UUID field added --- model_utils/fields.py | 60 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/model_utils/fields.py b/model_utils/fields.py index 2799eac..5bb630e 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -1,11 +1,19 @@ from __future__ import unicode_literals import django +try: + import uuid # noqa + HAS_UUID = True +except ImportError: + HAS_UUID = False from django.db import models from django.conf import settings +from django.core.exceptions import ImproperlyConfigured from django.utils.encoding import python_2_unicode_compatible from django.utils.timezone import now +from model_utils.exceptions import UUIDVersionException + DEFAULT_CHOICES_NAME = 'STATUS' @@ -17,6 +25,7 @@ class AutoCreatedField(models.DateTimeField): By default, sets editable=False, default=datetime.now. """ + def __init__(self, *args, **kwargs): kwargs.setdefault('editable', False) kwargs.setdefault('default', now) @@ -30,6 +39,7 @@ class AutoLastModifiedField(AutoCreatedField): By default, sets editable=False and default=datetime.now. """ + def pre_save(self, model_instance, add): value = now() if not model_instance.pk: @@ -53,6 +63,7 @@ class StatusField(models.CharField): Also features a ``no_check_for_status`` argument to make sure South can handle this field when it freezes a model. """ + def __init__(self, *args, **kwargs): kwargs.setdefault('max_length', 100) self.check_for_status = not kwargs.pop('no_check_for_status', False) @@ -93,6 +104,7 @@ class MonitorField(models.DateTimeField): changes. """ + def __init__(self, *args, **kwargs): kwargs.setdefault('default', now) monitor = kwargs.pop('monitor', None) @@ -144,7 +156,8 @@ SPLIT_MARKER = getattr(settings, 'SPLIT_MARKER', '') # the number of paragraphs after which to split if no marker SPLIT_DEFAULT_PARAGRAPHS = getattr(settings, 'SPLIT_DEFAULT_PARAGRAPHS', 2) -_excerpt_field_name = lambda name: '_%s_excerpt' % name + +def _excerpt_field_name(name): return '_%s_excerpt' % name def get_excerpt(content): @@ -252,3 +265,48 @@ class SplitField(models.TextField): name, path, args, kwargs = super(SplitField, self).deconstruct() kwargs['no_excerpt_field'] = True return name, path, args, kwargs + + +class UUIDField(models.UUIDField): + """ + A field for storing universally unique identifiers. Uses Python’s UUID class. + """ + + def __init__(self, primary_key=True, version=4, editable=False, *args, **kwargs): + """ + Parameters + ---------- + primary_key : bool + If True, this field is the primary key for the model. + version : int + An integer that set default UUID version. + editable : bool + If False, the field will not be displayed in the admin or any other ModelForm, + default is false. + + Raises + ------ + UUIDVersionException + UUID version 2 is not supported. + """ + if not HAS_UUID: + raise ImproperlyConfigured("'uuid' module is required for UUIDField.") + + kwargs.setdefault('primary_key', primary_key) + kwargs.setdefault('editable', editable) + + if version == 4: + default = uuid.uuid4 + elif version == 1: + default = uuid.uuid1 + elif version == 2: + raise UUIDVersionException("UUID version 2 is not supported.") + elif version == 3: + default = uuid.uuid3 + elif version == 5: + default = uuid.uuid5 + else: + raise UUIDVersionException("UUID version %s is not valid." % version) + + kwargs.setdefault('default', default) + super(UUIDField, self).__init__(*args, **kwargs) From 5bf7db036fde92b0752aeb3869bd679465be7584 Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:34:20 +0100 Subject: [PATCH 03/24] UUIDModel doc --- docs/models.rst | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/models.rst b/docs/models.rst index 51bde8f..4e04c29 100644 --- a/docs/models.rst +++ b/docs/models.rst @@ -55,3 +55,24 @@ SoftDeletableModel This abstract base class just provides field ``is_removed`` which is set to True instead of removing the instance. Entities returned in default manager are limited to not-deleted instances. + + +UUIDModel +------------------ + +This abstract base class provides ``id`` field on any model that inherits from it +which will be the primary key. + +If you dont want to set ``id`` as primary key or change the field name, you can be override it +with our [UUIDField](https://github.com/jazzband/django-model-utils/blob/master/docs/fields.rst#uuidfield). + +Also you can override the default uuid version. Versions 1,3,4 and 5 are now supported. + +.. code-block:: python + + from model_utils.models import UUIDModel + from model_utils import Choices + + class MyAppModel(UUIDModel): + pass + From bdc6fb05fecdf9ab68ee0f6f62fdb76209b94b7a Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:35:00 +0100 Subject: [PATCH 04/24] UUIDField doc --- docs/fields.rst | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/docs/fields.rst b/docs/fields.rst index 02ca6ef..1f0d5c5 100644 --- a/docs/fields.rst +++ b/docs/fields.rst @@ -154,3 +154,29 @@ If no marker is found in the content, the first two paragraphs (where paragraphs are blocks of text separated by a blank line) are taken to be the excerpt. This number can be customized by setting the ``SPLIT_DEFAULT_PARAGRAPHS`` setting. + + +UUIDField +---------- + +A ``UUIDField``subclass that provides an UUID field. You can +add this field to any model definition. + +With the param ``primary_key`` you can set if this field is the +primary key for the model, default is True. + +Param ``version`` is an integer that set default UUID version. +Versions 1,3,4 and 5 are supported, default is 4. + +If ``editable`` is set to false the field will not be displayed in the admin +or any other ModelForm, default is False. + + +.. code-block:: python + + from django.db import models + from model_utils.fields import UUIDField + + class MyAppModel(models.Model): + uuid = UUIDField(primary_key=True, version=4, editable=False) + From 5ff0867bf92dd06ac3bc8aa4e168ae64c2c3a07f Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:35:50 +0100 Subject: [PATCH 05/24] UUIDModels for testing purposes --- tests/models.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/models.py b/tests/models.py index 888aba5..72e48a4 100644 --- a/tests/models.py +++ b/tests/models.py @@ -8,7 +8,12 @@ from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from model_utils import Choices -from model_utils.fields import SplitField, MonitorField, StatusField +from model_utils.fields import ( + SplitField, + MonitorField, + StatusField, + UUIDField, +) from model_utils.managers import ( QueryManager, InheritanceManager, @@ -19,6 +24,7 @@ from model_utils.models import ( StatusModel, TimeFramedModel, TimeStampedModel, + UUIDModel, ) from tests.fields import MutableField from tests.managers import CustomSoftDeleteManager @@ -159,8 +165,8 @@ class Post(models.Model): objects = models.Manager() public = QueryManager(published=True) - public_confirmed = QueryManager(models.Q(published=True) & - models.Q(confirmed=True)) + public_confirmed = QueryManager(models.Q(published=True) + & models.Q(confirmed=True)) public_reversed = QueryManager(published=True).order_by("-order") class Meta: @@ -340,6 +346,7 @@ class StringyDescriptor(object): """ Descriptor that returns a string version of the underlying integer value. """ + def __init__(self, name): self.name = name @@ -393,3 +400,11 @@ class JoinItemForeignKey(models.Model): on_delete=models.CASCADE ) objects = JoinManager() + + +class CustomUUIDModel(UUIDModel): + pass + + +class CustomNotPrimaryUUIDModel(models.Model): + uuid = UUIDField(primary_key=False) From 58e57d55356eb9fdc3e78b38b9e38389e7798b8d Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:36:23 +0100 Subject: [PATCH 06/24] UUIDField tests --- tests/test_fields/test_uuid_field.py | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/test_fields/test_uuid_field.py diff --git a/tests/test_fields/test_uuid_field.py b/tests/test_fields/test_uuid_field.py new file mode 100644 index 0000000..74faa4f --- /dev/null +++ b/tests/test_fields/test_uuid_field.py @@ -0,0 +1,34 @@ +from __future__ import unicode_literals + +import uuid + +from django.test import TestCase + +from model_utils.fields import UUIDField +from model_utils.exceptions import UUIDVersionException + + +class UUIDFieldTests(TestCase): + + def test_uuid_version_default(self): + instance = UUIDField() + self.assertEqual(instance.default, uuid.uuid4) + + def test_uuid_version_1(self): + instance = UUIDField(version=1) + self.assertEqual(instance.default, uuid.uuid1) + + def test_uuid_version_2_error(self): + self.assertRaises(UUIDVersionException, UUIDField, 'version', 2) + + def test_uuid_version_3(self): + instance = UUIDField(version=3) + self.assertEqual(instance.default, uuid.uuid3) + + def test_uuid_version_4(self): + instance = UUIDField(version=4) + self.assertEqual(instance.default, uuid.uuid4) + + def test_uuid_version_5(self): + instance = UUIDField(version=5) + self.assertEqual(instance.default, uuid.uuid5) From c23c622d17b24bcb83eb009a606806028898889e Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:36:35 +0100 Subject: [PATCH 07/24] UUIDModel tests --- tests/test_models/test_uuid_model.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/test_models/test_uuid_model.py diff --git a/tests/test_models/test_uuid_model.py b/tests/test_models/test_uuid_model.py new file mode 100644 index 0000000..5559159 --- /dev/null +++ b/tests/test_models/test_uuid_model.py @@ -0,0 +1,20 @@ +from __future__ import unicode_literals + +from django.test import TestCase + +from tests.models import CustomUUIDModel, CustomNotPrimaryUUIDModel + + +class UUIDFieldTests(TestCase): + + def test_uuid_model_with_uuid_field_as_primary_key(self): + instance = CustomUUIDModel() + instance.save() + self.assertEqual(instance.id.__class__.__name__, 'UUID') + self.assertEqual(instance.id, instance.pk) + + def test_uuid_model_with_uuid_field_as_not_primary_key(self): + instance = CustomNotPrimaryUUIDModel() + instance.save() + self.assertEqual(instance.uuid.__class__.__name__, 'UUID') + self.assertNotEqual(instance.uuid, instance.pk) From 533501753f98b417b8569bc6ffab3f143fc4f64c Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:36:59 +0100 Subject: [PATCH 08/24] UUID version custom exception --- model_utils/exceptions.py | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 model_utils/exceptions.py diff --git a/model_utils/exceptions.py b/model_utils/exceptions.py new file mode 100644 index 0000000..90566cb --- /dev/null +++ b/model_utils/exceptions.py @@ -0,0 +1,2 @@ +class UUIDVersionException(Exception): + pass From 430866abfaca568ed9486e4199d9aad3d07d5253 Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:37:24 +0100 Subject: [PATCH 09/24] Update authors file --- AUTHORS.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS.rst b/AUTHORS.rst index 06a3e01..07e9967 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -50,4 +50,4 @@ | Jack Cushman | Zach Cheung | Daniel Andrlik - +| marfyl \ No newline at end of file From 015dd4831fbf887c7a26eb12802662ffd17d4949 Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:50:32 +0100 Subject: [PATCH 10/24] Catch error with inherit class --- model_utils/fields.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/model_utils/fields.py b/model_utils/fields.py index 5bb630e..6c43ecc 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -1,14 +1,9 @@ from __future__ import unicode_literals import django -try: - import uuid # noqa - HAS_UUID = True -except ImportError: - HAS_UUID = False +import uuid from django.db import models from django.conf import settings -from django.core.exceptions import ImproperlyConfigured from django.utils.encoding import python_2_unicode_compatible from django.utils.timezone import now @@ -289,9 +284,6 @@ class UUIDField(models.UUIDField): UUIDVersionException UUID version 2 is not supported. """ - if not HAS_UUID: - raise ImproperlyConfigured("'uuid' module is required for UUIDField.") - kwargs.setdefault('primary_key', primary_key) kwargs.setdefault('editable', editable) From 2f142afd379a09ee69840e04e7a12fb279b13b65 Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 17:55:02 +0100 Subject: [PATCH 11/24] Fix imports pep8 --- model_utils/models.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/model_utils/models.py b/model_utils/models.py index 0cfafe6..96c472b 100644 --- a/model_utils/models.py +++ b/model_utils/models.py @@ -1,12 +1,22 @@ from __future__ import unicode_literals -from model_utils.managers import QueryManager, SoftDeletableManager -from model_utils.fields import AutoCreatedField, AutoLastModifiedField, StatusField, MonitorField, UUIDField - import django from django.core.exceptions import ImproperlyConfigured from django.db import models from django.utils.translation import ugettext_lazy as _ + +from model_utils.fields import ( + AutoCreatedField, + AutoLastModifiedField, + StatusField, + MonitorField, + UUIDField, +) +from model_utils.managers import ( + QueryManager, + SoftDeletableManager, +) + if django.VERSION >= (1, 9, 0): from django.db.models.functions import Now now = Now() From e5955f780b57c5229a7cd26f219deb8bb5e061c7 Mon Sep 17 00:00:00 2001 From: jmmp Date: Tue, 26 Feb 2019 17:58:20 +0100 Subject: [PATCH 12/24] Update fields.py --- model_utils/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/model_utils/fields.py b/model_utils/fields.py index 5bb630e..ff10e51 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -157,7 +157,7 @@ SPLIT_MARKER = getattr(settings, 'SPLIT_MARKER', '') SPLIT_DEFAULT_PARAGRAPHS = getattr(settings, 'SPLIT_DEFAULT_PARAGRAPHS', 2) -def _excerpt_field_name(name): return '_%s_excerpt' % name +_excerpt_field_name = lambda name: '_%s_excerpt' % name def get_excerpt(content): From 000c70de9eb6dae0a304a03cb3faf492548daca7 Mon Sep 17 00:00:00 2001 From: jmmp Date: Tue, 26 Feb 2019 18:04:13 +0100 Subject: [PATCH 13/24] Update fields.rst --- docs/fields.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fields.rst b/docs/fields.rst index 1f0d5c5..87c298e 100644 --- a/docs/fields.rst +++ b/docs/fields.rst @@ -159,7 +159,7 @@ be the excerpt. This number can be customized by setting the UUIDField ---------- -A ``UUIDField``subclass that provides an UUID field. You can +A ``UUIDField`` subclass that provides an UUID field. You can add this field to any model definition. With the param ``primary_key`` you can set if this field is the From a6fc51c0b5e57858c93770fb36d5444793b5c8ff Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 18:10:42 +0100 Subject: [PATCH 14/24] Docs updated --- docs/fields.rst | 2 +- docs/models.rst | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/fields.rst b/docs/fields.rst index 1f0d5c5..87c298e 100644 --- a/docs/fields.rst +++ b/docs/fields.rst @@ -159,7 +159,7 @@ be the excerpt. This number can be customized by setting the UUIDField ---------- -A ``UUIDField``subclass that provides an UUID field. You can +A ``UUIDField`` subclass that provides an UUID field. You can add this field to any model definition. With the param ``primary_key`` you can set if this field is the diff --git a/docs/models.rst b/docs/models.rst index 4e04c29..48afa0d 100644 --- a/docs/models.rst +++ b/docs/models.rst @@ -64,7 +64,9 @@ This abstract base class provides ``id`` field on any model that inherits from i which will be the primary key. If you dont want to set ``id`` as primary key or change the field name, you can be override it -with our [UUIDField](https://github.com/jazzband/django-model-utils/blob/master/docs/fields.rst#uuidfield). +with our `UUIDField`_ + +(https://github.com/jazzband/django-model-utils/blob/master/docs/fields.rst#uuidfield). Also you can override the default uuid version. Versions 1,3,4 and 5 are now supported. @@ -76,3 +78,6 @@ Also you can override the default uuid version. Versions 1,3,4 and 5 are now sup class MyAppModel(UUIDModel): pass + + +.. _`UUIDField`: https://github.com/jazzband/django-model-utils/blob/master/docs/fields.rst#uuidfield \ No newline at end of file From 9b6f14bedd928eb670e0963c50f900f37e40481c Mon Sep 17 00:00:00 2001 From: jmmp Date: Tue, 26 Feb 2019 18:12:06 +0100 Subject: [PATCH 15/24] Update models.rst --- docs/models.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/models.rst b/docs/models.rst index 48afa0d..1c63c76 100644 --- a/docs/models.rst +++ b/docs/models.rst @@ -66,8 +66,6 @@ which will be the primary key. If you dont want to set ``id`` as primary key or change the field name, you can be override it with our `UUIDField`_ -(https://github.com/jazzband/django-model-utils/blob/master/docs/fields.rst#uuidfield). - Also you can override the default uuid version. Versions 1,3,4 and 5 are now supported. .. code-block:: python @@ -80,4 +78,4 @@ Also you can override the default uuid version. Versions 1,3,4 and 5 are now sup -.. _`UUIDField`: https://github.com/jazzband/django-model-utils/blob/master/docs/fields.rst#uuidfield \ No newline at end of file +.. _`UUIDField`: https://github.com/jazzband/django-model-utils/blob/master/docs/fields.rst#uuidfield From 8d9a00b89b2e9b5125c4e753aaa92f1e0a953d6a Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 18:16:01 +0100 Subject: [PATCH 16/24] Fix pep8 error --- tests/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/models.py b/tests/models.py index 72e48a4..ee1208e 100644 --- a/tests/models.py +++ b/tests/models.py @@ -165,8 +165,8 @@ class Post(models.Model): objects = models.Manager() public = QueryManager(published=True) - public_confirmed = QueryManager(models.Q(published=True) - & models.Q(confirmed=True)) + public_confirmed = QueryManager( + models.Q(published=True) & models.Q(confirmed=True)) public_reversed = QueryManager(published=True).order_by("-order") class Meta: From da3c59a6df56b5974823394ce0d4c7fd75efad63 Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 18:38:39 +0100 Subject: [PATCH 17/24] Fix SyntaxError for python 2.7 --- model_utils/fields.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/model_utils/fields.py b/model_utils/fields.py index e0ac7ba..6ad2b66 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -152,7 +152,7 @@ SPLIT_MARKER = getattr(settings, 'SPLIT_MARKER', '') SPLIT_DEFAULT_PARAGRAPHS = getattr(settings, 'SPLIT_DEFAULT_PARAGRAPHS', 2) -_excerpt_field_name = lambda name: '_%s_excerpt' % name +def _excerpt_field_name(name): return '_%s_excerpt' % name def get_excerpt(content): @@ -264,7 +264,7 @@ class SplitField(models.TextField): class UUIDField(models.UUIDField): """ - A field for storing universally unique identifiers. Uses Python’s UUID class. + A field for storing universally unique identifiers. Use Python UUID class. """ def __init__(self, primary_key=True, version=4, editable=False, *args, **kwargs): From 5c49f2c7d00a24728b825652f2a1e5382a9985d7 Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 18:41:23 +0100 Subject: [PATCH 18/24] Update changes.rst for UUIDModel and UUIDField --- CHANGES.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.rst b/CHANGES.rst index 629c4dc..9f2e6ff 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,6 +14,7 @@ master (unreleased) - Fix patched `save` in FieldTracker - Upgrades test requirements (pytest, pytest-django, pytest-cov) and skips tox test with Python 3.5 and Django (trunk) +- Add UUIDModel and UUIDField support. 3.1.2 (2018.05.09) ------------------ From 2a47aa093de48e135a83733fef3ea6cbeac5ff0e Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 19:01:39 +0100 Subject: [PATCH 19/24] Pep8 review --- model_utils/fields.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/model_utils/fields.py b/model_utils/fields.py index 6ad2b66..5816d7a 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -292,13 +292,15 @@ class UUIDField(models.UUIDField): elif version == 1: default = uuid.uuid1 elif version == 2: - raise UUIDVersionException("UUID version 2 is not supported.") + raise UUIDVersionException( + 'UUID version 2 is not supported.') elif version == 3: default = uuid.uuid3 elif version == 5: default = uuid.uuid5 else: - raise UUIDVersionException("UUID version %s is not valid." % version) + raise UUIDVersionException( + 'UUID version is not valid.') kwargs.setdefault('default', default) super(UUIDField, self).__init__(*args, **kwargs) From ce3a0e59f4f552c6e2ae24e32587c22d5d5c9f07 Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 19:17:06 +0100 Subject: [PATCH 20/24] Use django exception instead custom one --- model_utils/exceptions.py | 2 -- model_utils/fields.py | 12 ++++++------ 2 files changed, 6 insertions(+), 8 deletions(-) delete mode 100644 model_utils/exceptions.py diff --git a/model_utils/exceptions.py b/model_utils/exceptions.py deleted file mode 100644 index 90566cb..0000000 --- a/model_utils/exceptions.py +++ /dev/null @@ -1,2 +0,0 @@ -class UUIDVersionException(Exception): - pass diff --git a/model_utils/fields.py b/model_utils/fields.py index 5816d7a..952b726 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -4,11 +4,10 @@ import django import uuid from django.db import models from django.conf import settings +from django.core.exceptions import ValidationError from django.utils.encoding import python_2_unicode_compatible from django.utils.timezone import now -from model_utils.exceptions import UUIDVersionException - DEFAULT_CHOICES_NAME = 'STATUS' @@ -152,7 +151,8 @@ SPLIT_MARKER = getattr(settings, 'SPLIT_MARKER', '') SPLIT_DEFAULT_PARAGRAPHS = getattr(settings, 'SPLIT_DEFAULT_PARAGRAPHS', 2) -def _excerpt_field_name(name): return '_%s_excerpt' % name +def _excerpt_field_name(name): + return '_%s_excerpt' % name def get_excerpt(content): @@ -281,7 +281,7 @@ class UUIDField(models.UUIDField): Raises ------ - UUIDVersionException + ValidationError UUID version 2 is not supported. """ kwargs.setdefault('primary_key', primary_key) @@ -292,14 +292,14 @@ class UUIDField(models.UUIDField): elif version == 1: default = uuid.uuid1 elif version == 2: - raise UUIDVersionException( + raise ValidationError( 'UUID version 2 is not supported.') elif version == 3: default = uuid.uuid3 elif version == 5: default = uuid.uuid5 else: - raise UUIDVersionException( + raise ValidationError( 'UUID version is not valid.') kwargs.setdefault('default', default) From 89fd5fff82809266b119b14067aa9856c7e9ba7a Mon Sep 17 00:00:00 2001 From: JMP Date: Tue, 26 Feb 2019 19:19:32 +0100 Subject: [PATCH 21/24] Catch exception in test --- tests/test_fields/test_uuid_field.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_fields/test_uuid_field.py b/tests/test_fields/test_uuid_field.py index 74faa4f..85341f4 100644 --- a/tests/test_fields/test_uuid_field.py +++ b/tests/test_fields/test_uuid_field.py @@ -2,10 +2,10 @@ from __future__ import unicode_literals import uuid +from django.core.exceptions import ValidationError from django.test import TestCase from model_utils.fields import UUIDField -from model_utils.exceptions import UUIDVersionException class UUIDFieldTests(TestCase): @@ -19,7 +19,7 @@ class UUIDFieldTests(TestCase): self.assertEqual(instance.default, uuid.uuid1) def test_uuid_version_2_error(self): - self.assertRaises(UUIDVersionException, UUIDField, 'version', 2) + self.assertRaises(ValidationError, UUIDField, 'version', 2) def test_uuid_version_3(self): instance = UUIDField(version=3) From 5ffcfe831c609ecd4c2f781e789fbe3c05e913b7 Mon Sep 17 00:00:00 2001 From: jmmp Date: Wed, 27 Feb 2019 02:29:47 +0100 Subject: [PATCH 22/24] Update fields.py --- model_utils/fields.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/model_utils/fields.py b/model_utils/fields.py index 952b726..701147b 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -284,23 +284,25 @@ class UUIDField(models.UUIDField): ValidationError UUID version 2 is not supported. """ - kwargs.setdefault('primary_key', primary_key) - kwargs.setdefault('editable', editable) - - if version == 4: - default = uuid.uuid4 - elif version == 1: - default = uuid.uuid1 - elif version == 2: + + if version == 2: raise ValidationError( 'UUID version 2 is not supported.') - elif version == 3: - default = uuid.uuid3 - elif version == 5: - default = uuid.uuid5 - else: + + if version < 1 or version > 5: raise ValidationError( 'UUID version is not valid.') - + + if version == 1: + default = uuid.uuid1 + elif version == 3: + default = uuid.uuid3 + elif version == 4: + default = uuid.uuid4 + elif version == 5: + default = uuid.uuid5 + + kwargs.setdefault('primary_key', primary_key) + kwargs.setdefault('editable', editable) kwargs.setdefault('default', default) super(UUIDField, self).__init__(*args, **kwargs) From 434bc6d45c59c5794ab9ecf22ade8ec27274db51 Mon Sep 17 00:00:00 2001 From: jmmp Date: Wed, 27 Feb 2019 14:33:48 +0100 Subject: [PATCH 23/24] unneeded import removed --- docs/models.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/models.rst b/docs/models.rst index 1c63c76..255826c 100644 --- a/docs/models.rst +++ b/docs/models.rst @@ -71,7 +71,6 @@ Also you can override the default uuid version. Versions 1,3,4 and 5 are now sup .. code-block:: python from model_utils.models import UUIDModel - from model_utils import Choices class MyAppModel(UUIDModel): pass From fc523d543392b9ef7d5b8b6c8ec962b151552e42 Mon Sep 17 00:00:00 2001 From: JMP Date: Wed, 20 Mar 2019 21:51:31 +0100 Subject: [PATCH 24/24] Add tdd to increase coverage --- tests/test_fields/test_uuid_field.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_fields/test_uuid_field.py b/tests/test_fields/test_uuid_field.py index 85341f4..3a6c739 100644 --- a/tests/test_fields/test_uuid_field.py +++ b/tests/test_fields/test_uuid_field.py @@ -32,3 +32,9 @@ class UUIDFieldTests(TestCase): def test_uuid_version_5(self): instance = UUIDField(version=5) self.assertEqual(instance.default, uuid.uuid5) + + def test_uuid_version_bellow_min(self): + self.assertRaises(ValidationError, UUIDField, 'version', 0) + + def test_uuid_version_above_max(self): + self.assertRaises(ValidationError, UUIDField, 'version', 6)