9

Newbie here. Trying to build an app using Django and Postgres db. I am struggling to migrate at the moment getting this error "KeyError: ('profiles', 'talk')"

Here is my error from my command line after trying to migrate:

(myvenv) Abbys-iMac:talks abbyhumphreys$ python manage.py migrate
/Users/abbyhumphreys/talks/myvenv/lib/python3.4/site-packages/django/contrib/sites/models.py:78: RemovedInDjango19Warning: Model class django.contrib.sites.models.Site doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. This will no longer be supported in Django 1.9.
class Site(models.Model):

System check identified some issues:

WARNINGS:
profiles.Profile.user: (fields.W342) Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.
HINT: ForeignKey(unique=True) is usually better served by a OneToOneField.
registration.RegistrationProfile.user: (fields.W342) Setting unique=True on a   ForeignKey has the same effect as using a OneToOneField.
HINT: ForeignKey(unique=True) is usually better served by a OneToOneField.
Operations to perform:
Synchronize unmigrated apps: staticfiles, registration, humanize, messages
Apply all migrations: profiles, auth, sessions, admin, contenttypes
Synchronizing apps without migrations:
Creating tables...
    Running deferred SQL...
    Installing custom SQL...
Running migrations:
    Rendering model states...Traceback (most recent call last):
    File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
    File "/Users/abbyhumphreys/talks/myvenv/lib/python3.4/site-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
utility.execute()
    File "/Users/abbyhumphreys/talks/myvenv/lib/python3.4/site-packages/django/core/management/__init__.py", line 330, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
    File "/Users/abbyhumphreys/talks/myvenv/lib/python3.4/site-packages/django/core/management/base.py", line 390, in run_from_argv
self.execute(*args, **cmd_options)
    File "/Users/abbyhumphreys/talks/myvenv/lib/python3.4/site-packages/django/core/management/base.py", line 441, in execute
output = self.handle(*args, **options)
    File "/Users/abbyhumphreys/talks/myvenv/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 221, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
    File "/Users/abbyhumphreys/talks/myvenv/lib/python3.4/site-packages/django/db/migrations/executor.py", line 104, in migrate
state = migration.mutate_state(state, preserve=do_run)
    File "/Users/abbyhumphreys/talks/myvenv/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/abbyhumphreys/talks/myvenv/lib/python3.4/site-packages/django/db/migrations/operations/fields.py", line 256, in state_forwards
for n, f in state.models[app_label, self.model_name_lower].fields
KeyError: ('profiles', 'talk')

Here is my models.py:

from django.contrib.auth.models import User
from django.db import models

class Profile(models.Model):
    name = models.CharField(max_length=255)
    sname = models.CharField(max_length=255, blank=True, null=True)
    phone = models.CharField(max_length=255, blank=True, null=True)
    mobile = models.CharField(max_length=255, blank=True, null=True)
    email = models.EmailField(max_length=254, blank=True, null=True)
    address = models.TextField(blank=True, null=True)
    notes = models.TextField()
    slug = models.SlugField(unique=True)
    user = models.ForeignKey(User, unique=True, blank=True, null=True, related_name="users")

class Talk(models.Model):
    talk_no = models.CharField(max_length=255, blank=True, null=True)
    talk_name = models.CharField(max_length=255, blank=True, null=True)
    slug = models.SlugField(unique=True)

class Congregation(models.Model):
    cong_name = models.CharField(max_length=255, blank=True, null=True)
    meeting_time = models.CharField(max_length=255, blank=True, null=True)
    cong_address = models.TextField(blank=True, null=True)
    cong_phone = models.CharField(max_length=255, blank=True, null=True)
    slug = models.SlugField(unique=True)

Here is my views.py:

from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.shortcuts import render, render_to_response, redirect
from django.template import RequestContext
from profiles.forms import ProfileForm, TalkForm, CongForm
from profiles.models import Profile, Talk, Congregation
from django.template.defaultfilters import slugify

def index(request):
    ids = Profile.objects.all()
    return render(request, 'index.html',{'ids': ids,})

def about(request):

    return render(request, 'about.html',)

def contact(request):

    return render(request, 'contact.html',)

def profile_detail(request, slug):
    #grab the object...
    profile=Profile.objects.get(slug=slug)
    #and pass to the template
    return render(request,'ids/profile_detail.html', {
        'profile': profile,
    })

@login_required
def edit_profile(request, slug):
    profile = Profile.objects.get(slug=slug)
    if profile.user != request.user:
        raise Http404

    form_class = ProfileForm

    if request.method == 'POST':
        form = form_class(data=request.POST, instance=profile)
        if form.is_valid():
            form.save()
            return redirect('profile_detail', slug=profile.slug)
    else:
        form = form_class(instance=profile)
    return render(request, 'ids/edit_profile.html', {'profile': profile, 'form': form, })

def create_profile(request):
    form_class = ProfileForm

    if request.method == 'POST':
        form=form_class(request.POST)
        if form.is_valid():
            profile=form.save(commit=False)
            profile.user = request.user
            profile.slug = slugify(profile.name)
            profile.save()
            slug = slugify(name)
        return redirect('profile_detail', slug=profile.slug)
    else:
        form=form_class()
    return render(request, 'ids/create_profile.html', {'form': form,})

def browse_by_name(request, initial=None):
    if initial:
        ids = Profile.objects.filter(name__istartswith=initial).order_by('name')
    else:
        ids = Profile.objects.all().order_by('name')

    return render_to_response('search/search.html', {'ids': ids, 'initial': initial,}, context_instance=RequestContext(request))

def talk_detail(request, slug):
    #grab the object...
    talk=Talk.objects.get(slug=slug)
    #and pass to the template
    return render(request,'ids/talk_detail.html', {
        'talk': talk,
    })

@login_required
def edit_talk(request, slug):
    talk = Talk.objects.get(slug=slug)
    if profile.user != request.user:
        raise Http404

    form_class = TalkForm

    if request.method == 'POST':
        form = form_class(data=request.POST, instance=talk)
        if form.is_valid():
            form.save()
            return redirect('talk_detail', slug=slug.slug)
    else:
        form = form_class(instance=talk)
    return render(request, 'ids/edit_talk.html', {'talk': talk, 'form': form,   })

def create_talk(request):
    form_class = TalkForm

    if request.method == 'POST':
        form=form_class(request.POST)
        if form.is_valid():
            talk=form.save(commit=False)
            profile.user = request.user
            talk.slug = slugify(talk.talk_no)
            talk.save()
            slug = slugify(talk_no)
        return redirect('talk_detail', slug=talk.slug)
    else:
        form=form_class()
    return render(request, 'ids/create_talk.html', {'form': form,})

def cong_detail(request, slug):
    #grab the object...
    cong=Congregation.objects.get(slug=slug)
    #and pass to the template
    return render(request,'ids/cong_detail.html', {
        'cong': cong,
    })

@login_required
def edit_cong(request, slug):
    cong = Congregation.objects.get(slug=slug)
    if profile.user != request.user:
        raise Http404

    form_class = CongForm

    if request.method == 'POST':
        form = form_class(data=request.POST, instance=cong)
        if form.is_valid():
            form.save()
            return redirect('cong_detail', slug=cong.slug)
    else:
        form = form_class(instance=cong)
    return render(request, 'ids/edit_cong.html', {'cong': cong, 'form': form, })

def create_cong(request):
    form_class = CongForm

    if request.method == 'POST':
        form=form_class(request.POST)
        if form.is_valid():
            cong=form.save(commit=False)
            profile.user = request.user
            cong.slug = slugify(cong.cong_name)
            cong.save()
            slug = slugify(cong_name)
        return redirect('cong_detail', slug=cong.slug)
    else:
        form=form_class()
    return render(request, 'ids/create_cong.html', {'form': form,})

Here is my url.py

from django.contrib import admin
from profiles.backends import MyRegistrationView
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.views.generic import TemplateView, RedirectView
from django.contrib.auth.views import password_reset, password_reset_done,  password_reset_confirm, password_reset_complete

urlpatterns = patterns('',
    url(r'^$', 'profiles.views.index', name='home'),
    url(r'^about/$', TemplateView.as_view(template_name='about.html'), name='about'),
    url(r'^contact/$', TemplateView.as_view(template_name='contact.html'), name='contact'),

    url(r'^ids/$', RedirectView.as_view(pattern_name='browse')),
    url(r'^ids/(?P<slug>[-\w]+)/$', 'profiles.views.profile_detail', name='profile_detail'),
    url(r'^ids/(?P<slug>[-\w]+)/edit/$', 'profiles.views.edit_profile', name='edit_profile'),

    url(r'^ids/(?P<slug>[-\w]+)/$', 'profiles.views.talk_detail', name='talk_detail'),
    url(r'^ids/(?P<slug>[-\w]+)/edit/$', 'profiles.views.edit_talk', name='edit_talk'),

    url(r'^ids/(?P<slug>[-\w]+)/$', 'profiles.views.cong_detail', name='cong_detail'),
    url(r'^ids/(?P<slug>[-\w]+)/edit/$', 'profiles.views.edit_cong', name='edit_cong'),

    url(r'^browse/$', RedirectView.as_view(pattern_name='browse')),
    url(r'^browse/name/$','profiles.views.browse_by_name', name='browse'),
    url(r'^browse/name/(?P<initial>[-\w]+)/$', 'profiles.views.browse_by_name', name='browse_by_name'),

    url(r'^accounts/password/reset/$', password_reset, 
    {'template_name': 'registration/password_reset_form.html'}, 
    name="password_reset"),
    url(r'^accounts/password/reset/done/$', 
    password_reset_done, 
    {'template_name': 'registration/password_reset_done.html'}, 
    name="password_reset_done"),
    url(r'^accounts/password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
    password_reset_confirm, 
    {'template_name': 'registration/password_reset_confirm.html'}, 
    name="password_reset_confirm"),
    url(r'^accounts/password/done/$', password_reset_complete,
    {'template_name': 'registration/password_reset_complete.html'},
    name="password_reset_complete"),

    url(r'^accounts/register/$', MyRegistrationView.as_view(), name='registration_register'),
    url(r'^accounts/create_profile/$', 'profiles.views.create_profile', name='registration_create_profile'),
    url(r'^accounts/create_talk/$', 'profiles.views.create_talk', name='registration_create_talk'),
    url(r'^accounts/create_cong/$', 'profiles.views.create_cong', name='registration_create_cong'),

    url(r'^accounts/', include('registration.backends.default.urls')),
    url(r'^admin/', include(admin.site.urls)),
)

Not sure if I've given too much or too little info, but being a newbie, I have no idea what the error means or what information you might need to figure it out!

Thank you in advance for your help in resolving this problem and your patience in looking at all my awful code! :-s

bibby3316
  • 103
  • 1
  • 1
  • 6
  • Were you able to solve this? I'm having the same problem, stuck now :( – Noel Pure Aug 01 '15 at 00:26
  • 2
    I had a similar error and it works for me to remove all automatically generated files from `migrations` folder (so everything except `__init__.py`) and then run `makemigrations` and `migrate` to make them again. – Marta Cz-C Jan 23 '17 at 11:27

8 Answers8

4

This happens when you do the following steps:

  1. Run

migrate appname

and execution stopped because of an error.

  1. You run it again, but this time its an error because the new table is already created.

  2. You edit the migration file, remove the code part creating the table, then run the migration again.

My workaround is, instead of removing CreateModel, I moved it to the previous migration file.

Noel Pure
  • 422
  • 2
  • 13
  • Running migrations twice is not harmful. Furthermore I don't think noobs (i.e. OP) should be messing with the migrations. – Chris Jun 12 '18 at 13:14
  • Thank you! the idea of putting the part of code related to previously created db was incisve. – Green Falcon Dec 31 '21 at 15:27
1

You better to show the code of your migration files in this issue because the problem probably is there.

It might be that you didn't have a migration file where you created your model with name talk.

Problem could be solved with adding creation of talk model into one of the migration files.

Roberto
  • 1,472
  • 2
  • 16
  • 18
  • This was the case for me. After an error 1054 https://stackoverflow.com/a/51881452/3747731, I had to recreate manually a field + `migrate --fake`. But in my **empty migration** I copied/pasted a piece of another migration file and forgot to change the app/model name of the field I wanted to create. – Abpostman1 Nov 09 '22 at 10:02
1

I had built my own "wheel-package" (the things that you can install with pip install <filename>) and after deploying it and going ./manage.py migrate, ran into this problem.

This is how I found out what the problem was:

On my dev-box, I deleted all migrations, ran makemigrations and built a new package. After deploying the new package to the test-box and deleting the database to start from scratch, migrate would still try to apply old migration-files it should not have known about.

I found that the build-process somehow did not clean the migrations-folder (in my case at /<app>/build/lib/<app>/migrations/) which held older migration-files from earlier attempts to mess with the model. So there were multiple versions of 0001* etc and Django tried to apply them all.

I deleted the /build-directory and let the script create it from scratch.

Chris
  • 5,788
  • 4
  • 29
  • 40
1

The reason for the key error is that the migration plan did not load the model state for the model you are modifying. In order for the plan to load that model, it needs to find a CreateModel instruction somewhere in your migration tree (by migration tree I mean the tree that is built when you traverse the "dependencies" portion of the migration).

If that tree never leads to a migration with a CreateModel statement for your model, then it will not be in the plan.

Add a dependency pointing to the one that contains the CreateModel instruction to the migration in question and things should work out well.

0

This error hit me when I edited the migration file but didn't notice that I had placed one AddField() for a field before the model for that field was created. Maybe helps someone.

wanaryytel
  • 3,352
  • 2
  • 18
  • 26
  • Yes. I think the takeaway should be: don't edit your migrations unless you know what you're doing. – Chris Jun 12 '18 at 13:15
0

Newbie here too, suffering the same problem, although I appreciate the thread has long gone cold. I followed the latest Django 2.1 tutorial, then tried to migrate my app into a separate 'Django-app' package.

I kept getting the KeyError originating in state.models[app_label, self.model_name_lower].fields

@Chris' suggestion above was a great help. I'm using Mac OS High Sierra and so I went to my ~/.virtualenvs/env/lib/python3.7/site-packages and deleted anything I'd created since the original install, including the version of the App before I'd packaged it as Django-app.

It still didn't work, so I found one more step was needed.I found all manner of junk in ~/Library/Caches/pip/wheels which I deleted. I also deleted the Django db from my mySQL database.

I then created a new Django superuser; remade migrations and ran them.

Now it's working just great.

Hope this helps another very frustrated noob like me.

0

I got this error when one of my migrations was not executed successfully.

To reproduce the problem do the following in your django application:

  • Disable all modules except the one you couldn't migrate.
  • Check with ./manage.py showmigrations whether all your migrations have been applied.
Tobias Ernst
  • 4,214
  • 1
  • 32
  • 30
0

While this may not answer the original question, I did receive a similar error but because of a different reason so I'd like to chip in with my solution.

I went through a small refactoring where I changed the name of a model. With that, changes to variable names and other code occurrences came along. It turned out that during the refactoring I accidentally made changes to previous migrations. I fixed this silly mistake by going through the migration files and make sure the model names were correct