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

prevent migration errors on django 1.8 by declaring the SafeDeleteManager (internal class in managers) as global #38

Merged
merged 1 commit into from
Nov 23, 2015

Conversation

barseghyanartur
Copy link
Contributor

myapp/models.py

    from django.utils import six, timezone
    from django.db import models
    from django.contrib.auth.models import (
        AbstractBaseUser, PermissionsMixin, BaseUserManager
    )
    from django.core.mail import send_mail
    from django.utils.translation import ugettext_lazy as _

    from safedelete.models import safedelete_mixin_factory
    from safedelete.utils import SOFT_DELETE

    class UserManager(BaseUserManager):
        """
        User manager.
        """
        use_in_migrations = True

        def _create_user(self, email, password,
                         is_staff, is_superuser, **extra_fields):
            """
            Creates and saves a User with the given username, email and password.
            """
            now = timezone.now()
            if not email:
                raise ValueError('The given email must be set')
            email = self.normalize_email(email)
            user = self.model(email=email,
                              is_staff=is_staff, is_active=True,
                              is_superuser=is_superuser,
                              date_joined=now, **extra_fields)
            user.set_password(password)
            user.save(using=self._db)
            return user

        def create_user(self, email=None, password=None, **extra_fields):
            return self._create_user(email, password, False, False,
                                     **extra_fields)

        def create_superuser(self, email, password, **extra_fields):
            return self._create_user(email, password, True, True,
                                     **extra_fields)

    # Soft delete - models will be soft-deleted.
    SoftDeleteMixin = safedelete_mixin_factory(SOFT_DELETE,
                                               manager_superclass=UserManager)

    class User(SoftDeleteMixin, AbstractBaseUser, PermissionsMixin):
        """
        An abstract base class implementing a fully featured User model with
        admin-compliant permissions.

        Username, password and email are required. Other fields are optional.
        """
        first_name = models.CharField(_('first name'), max_length=30, null=True,
                                      blank=True)
        last_name = models.CharField(_('last name'), max_length=30, null=True,
                                     blank=True)
        email = models.EmailField(_('email address'), unique=True)
        is_staff = models.BooleanField(_('staff status'), default=False,
            help_text=_('Designates whether the user can log into this admin '
                        'site.'))
        is_active = models.BooleanField(_('active'), default=True,
            help_text=_('Designates whether this user should be treated as '
                        'active. Unselect this instead of deleting accounts.'))
        date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

        # Additional fields

        USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = []

        class Meta:
            app_label = 'myapp'
            verbose_name = _('User')
            verbose_name_plural = _('Users')

        def get_full_name(self):
            """
            Returns the first_name plus the last_name, with a space in between.
            """
            full_name = '%s %s' % (self.first_name, self.last_name)
            return full_name.strip()

        def get_short_name(self):
            "Returns the short name for the user."
            return self.first_name

        def email_user(self, subject, message, from_email=None, **kwargs):
            """
            Sends an email to this User.
            """
            send_mail(subject, message, from_email, [self.email], **kwargs)

why?

Without the change migrations (./manage.py makemigrations) fail. The traceback:

Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/user/.virtualenvs/myenv/lib/python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
    utility.execute()
  File "/home/user/.virtualenvs/myenv/lib/python3.4/site-packages/django/core/management/__init__.py", line 330, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/user/.virtualenvs/myenv/lib/python3.4/site-packages/django/core/management/base.py", line 393, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/user/.virtualenvs/myenv/lib/python3.4/site-packages/raven/contrib/django/management/__init__.py", line 41, in new_execute
    return original_func(self, *args, **kwargs)
  File "/home/user/.virtualenvs/myenv/lib/python3.4/site-packages/django/core/management/base.py", line 444, in execute
    output = self.handle(*args, **options)
  File "/home/user/.virtualenvs/myenv/lib/python3.4/site-packages/django/core/management/commands/makemigrations.py", line 99, in handle
    ProjectState.from_apps(apps),
  File "/home/user/.virtualenvs/myenv/lib/python3.4/site-packages/django/db/migrations/state.py", line 178, in from_apps
    model_state = ModelState.from_model(model)
  File "/home/user/.virtualenvs/myenv/lib/python3.4/site-packages/django/db/migrations/state.py", line 441, in from_model
    reconstruct_manager(model._default_manager)
  File "/home/user/.virtualenvs/myenv/lib/python3.4/site-packages/django/db/migrations/state.py", line 425, in reconstruct_manager
    as_manager, manager_path, qs_path, args, kwargs = mgr.deconstruct()
  File "/home/user/.virtualenvs/myenv/lib/python3.4/site-packages/django/db/models/manager.py", line 110, in deconstruct
    % (name, module_name)
ValueError: Could not find manager SafeDeleteManager in safedelete.managers.
Please note that you need to inherit from managers you dynamically generated with 'from_queryset()'.

@Gagaro
Copy link
Member

Gagaro commented Nov 23, 2015

Thanks for the fix 👍 .

Gagaro added a commit that referenced this pull request Nov 23, 2015
prevent migration errors on django 1.8 by declaring the SafeDeleteManager (internal class in managers) as global
@Gagaro Gagaro merged commit 316f295 into makinacorpus:master Nov 23, 2015
@Gagaro
Copy link
Member

Gagaro commented Nov 23, 2015

Released in 0.3.2

@barseghyanartur
Copy link
Contributor Author

@Gagaro:

Thanks for the quick release!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants