Glyn Jackson
Glyn Jackson

Reputation: 8354

Django TypeError: 'ModelBase' object is not iterable

I'm struggling to debug a vague error message in Django when executing any migration command:

Operations to perform:
  Synchronize unmigrated apps: rest_framework_docs, staticfiles, django_coverage, django_extensions, storages, corsheaders, gis, templated_email, rest_framework, django_mptt_admin, opbeat.contrib.django, grappelli, permissions, django_nose, django_markdown, messages, common
  Apply all migrations: contenttypes, auth, badges, reputation, geodata,  comments, sites, users, votes, watchers, library, sessions, admin, oauth2_provider
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  No migrations to apply.

    Traceback (most recent call last):
      File "manage.py", line 10, in <module>
        execute_from_command_line(sys.argv)
      File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 354, in execute_from_command_line
        utility.execute()
      File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 346, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/core/management/base.py", line 394, in run_from_argv
        self.execute(*args, **cmd_options)
      File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/core/management/base.py", line 445, in execute
        output = self.handle(*args, **options)
      File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 205, in handle
        executor.loader.project_state(),
      File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/db/migrations/loader.py", line 353, in project_state
        return self.graph.make_state(nodes=nodes, at_end=at_end, real_apps=list(self.unmigrated_apps))
      File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/db/migrations/graph.py", line 231, in make_state
        project_state = self.nodes[node].mutate_state(project_state, preserve=False)
      File "/Users/user/Documents/workspace/app-api/env/lib/python3.4/site-packages/django/db/migrations/migration.py", line 83, in mutate_state
        operation.state_forwards(self.app_label, new_state)
      File "/Users/user/Documents/workspace/user-api/env/lib/python3.4/site-packages/django/db/migrations/operations/models.py", line 52, in state_forwards
        tuple(self.bases),
    TypeError: 'ModelBase' object is not iterable

I've tracked the problem down to one of my apps, removing it clears the error. However, the error above does not help me understand the issue. Runserver works fine with no errors output.

The error is being generated from this line in Django: https://github.com/django/django/blob/master/django/db/migrations/operations/models.py#L83

What does this error relate to? The app itself does not generate any errors and runs fine, the app which gives this error is reputation.

Environment:

pillow==3.2.0
Django==1.8.7
psycopg2
Sphinx==1.2.3
django-mptt==0.7.2
sphinx_rtd_theme==0.1.6
django_extensions==1.3.3
django-mptt-admin==0.2.1
django-debug-toolbar==1.4
djangorestframework==3.3.3
django-oauth-toolkit==0.8.1
rest_condition==1.0.1
gevent==1.1rc3
gunicorn==19.3.0
django-cors-headers==1.1.0
django-simple-email-confirmation==0.12
itsdangerous==0.24
django-grappelli==2.7.1
numpy==1.11.0

reputation migrations:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals



class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('contenttypes', '0002_remove_content_type_name'),
    ]

    operations = [
        migrations.CreateModel(
            name='Reputation',
            fields=[
                ('created', django_extensions.db.fields.CreationDateTimeField(default=django.utils.timezone.now, blank=True, editable=False, verbose_name='created')),
                ('modified', django_extensions.db.fields.ModificationDateTimeField(default=django.utils.timezone.now, blank=True, editable=False, verbose_name='modified')),
                ('id', models.UUIDField(primary_key=True, unique=True,
                ('reputation', models.PositiveIntegerField(default=0)),
                ('dimension', models.CharField(max_length=2, blank=True, null=True)),
                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='reputation_set')),
            ],
            options={
                'verbose_name': 'Reputation',
            },
        ),
        migrations.CreateModel(
            name='ReputationAction',
            fields=[
                ('created', django_extensions.db.fields.CreationDateTimeField(default=django.utils.timezone.now, blank=True, editable=False, verbose_name='created')),
                ('modified', django_extensions.db.fields.ModificationDateTimeField(default=django.utils.timezone.now, blank=True, editable=False, verbose_name='modified')),
                ('id', models.UUIDField(primary_key=True, unique=True, 
                ('action_type', models.CharField(max_length=10, blank=True, null=True)),
                ('value', models.IntegerField(default=0)),
                ('capped', models.BooleanField(default=0)),
                ('object_id', models.UUIDField()),
                ('content_type', models.ForeignKey(to='contenttypes.ContentType')),
                ('originating_user', models.ForeignKey(related_name='originating_user', to=settings.AUTH_USER_MODEL, null=True)),
                ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='target_user')),
            ],
            options={
                'verbose_name': 'Reputation Action',
            },
            bases=(models.Model),
        ),
    ]

2:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
from django.conf import settings


class Migration(migrations.Migration):

    dependencies = [
        ('reputation', '0001_initial'),
    ]

    operations = [
        migrations.AlterField(
            model_name='reputationaction',
            name='user',
            field=models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='reputation_action'),
        ),
    ]

3

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


def dedupe_reputation_actions(apps, schema_editor):
    Reputation = apps.get_model('reputation', 'Reputation')

    qs = Reputation.objects.all().values('user', 'dimension')\
        .annotate(total=models.Count('user'))\
        .filter(total__gt=1)

    for dupe in qs:
        reps = list(Reputation.objects.filter(user=dupe['user'], dimension=dupe['dimension']))

        for rep in reps[1:]:
            rep.delete()


class Migration(migrations.Migration):

    dependencies = [
        ('reputation', '0002_auto_20151117_1108'),
    ]

    operations = [
        migrations.RunPython(dedupe_reputation_actions)
    ]

4

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('reputation', '0003_auto_20160302_1749'),
    ]

    operations = [
        migrations.AlterUniqueTogether(
            name='reputation',
            unique_together=set([('user', 'dimension')]),
        ),
    ]

Upvotes: 2

Views: 9862

Answers (1)

knbk
knbk

Reputation: 53649

In your first migration:

migrations.CreateModel(
    name='ReputationAction',
    ...
    bases=(models.Model),
),

You need to change bases=(models.Model), to bases=(models.Model,), (note the extra comma). This will make bases a tuple containing the base Model class, rather than just the model class.

I'm not sure how your migrations would get into this state. Did you change the migrations manually? You might want to upgrade Django to the latest 1.8.x version, maybe there was a bug that has since been fixed.

Upvotes: 7

Related Questions