Repository: agconti/cookiecutter-django-rest

Issue:
Upgrade user model `pk`s to `uuids`



Discussion:

Resolving patch:
diff --git a/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/migrations/0001_initial.py b/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/migrations/0001_initial.py
--- a/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/migrations/0001_initial.py
+++ b/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/migrations/0001_initial.py
@@ -1,35 +1,39 @@
 # -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-01-31 23:31
 from __future__ import unicode_literals
 
-from django.db import models, migrations
-import django.utils.timezone
-import django.core.validators
 import django.contrib.auth.models
+import django.core.validators
+from django.db import migrations, models
+import django.utils.timezone
+import uuid
 
 
 class Migration(migrations.Migration):
 
+    initial = True
+
     dependencies = [
-        ('auth', '0006_require_contenttypes_0002'),
+        ('auth', '0007_alter_validators_add_error_messages'),
     ]
 
     operations = [
         migrations.CreateModel(
             name='User',
             fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                 ('password', models.CharField(max_length=128, verbose_name='password')),
-                ('last_login', models.DateTimeField(null=True, verbose_name='last login', blank=True)),
+                ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
                 ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
-                ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, max_length=30, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.', 'invalid')], help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', unique=True, verbose_name='username')),
-                ('first_name', models.CharField(max_length=30, verbose_name='first name', blank=True)),
-                ('last_name', models.CharField(max_length=30, verbose_name='last name', blank=True)),
-                ('email', models.EmailField(max_length=254, verbose_name='email address', blank=True)),
+                ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, unique=True, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.')], verbose_name='username')),
+                ('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
+                ('last_name', models.CharField(blank=True, max_length=30, verbose_name='last name')),
+                ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
                 ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
                 ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
                 ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
-                ('groups', models.ManyToManyField(related_query_name='user', related_name='user_set', to='auth.Group', blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', verbose_name='groups')),
-                ('user_permissions', models.ManyToManyField(related_query_name='user', related_name='user_set', to='auth.Permission', blank=True, help_text='Specific permissions for this user.', verbose_name='user permissions')),
+                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
+                ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
+                ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
             ],
             options={
                 'abstract': False,
diff --git a/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/migrations/0002_auto_20151214_0053.py b/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/migrations/0002_auto_20151214_0053.py
deleted file mode 100644
--- a/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/migrations/0002_auto_20151214_0053.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.9 on 2015-12-14 00:53
-from __future__ import unicode_literals
-
-import django.core.validators
-from django.db import migrations, models
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('users', '0001_initial'),
-    ]
-
-    operations = [
-        migrations.AlterField(
-            model_name='user',
-            name='username',
-            field=models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=30, unique=True, validators=[django.core.validators.RegexValidator('^[\\w.@+-]+$', 'Enter a valid username. This value may contain only letters, numbers and @/./+/-/_ characters.')], verbose_name='username'),
-        ),
-    ]
diff --git a/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/models.py b/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/models.py
--- a/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/models.py
+++ b/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/models.py
@@ -1,13 +1,15 @@
 from __future__ import unicode_literals
 
-# from django.db import models
-# from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import python_2_unicode_compatible
+import uuid
+from django.db import models
 from django.contrib.auth.models import AbstractUser
+from django.utils.encoding import python_2_unicode_compatible
+# from django.utils.translation import ugettext_lazy as _
 
 
 @python_2_unicode_compatible
 class User(AbstractUser):
+    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
 
     def __str__(self):
         return self.username


Test patch:
diff --git a/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/test/factories.py b/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/test/factories.py
--- a/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/test/factories.py
+++ b/{{cookiecutter.github_repository_name}}/{{cookiecutter.app_name}}/users/test/factories.py
@@ -1,12 +1,13 @@
+import uuid
 import factory
 
-
 class UserFactory(factory.django.DjangoModelFactory):
 
     class Meta:
         model = 'users.User'
         django_get_or_create = ('username',)
 
+    id = factory.Sequence(lambda n: uuid.uuid4())
     username = factory.Sequence(lambda n: 'testuser{}'.format(n))
     password = factory.Faker('password', length=10, special_chars=True, digits=True, upper_case=True, lower_case=True)
     email = factory.Faker('email')