﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
22956	PermissionManager.get_by_natural_key doesn't fetch ContentType from same DB	jyrno@…	nobody	"Currently, when an user has multiple databases configured, and dumps
his auth.* tables using dumpdata command with --natural flag.
 
Then loads the dump to the other (non-default) database
there seems to be an issue with selecting the correct
content type for the permission from the specified database.
 
E.g. The PermissionManager gets the id in get_by_natural_key
from the default database while --database=other was explicitly
specified.
 
Note: This will all be ok, if both tables have been synced with the same
INSTALLED_APP setting. (since both databases have the same real ids, 
for content_type models.)

Issue was reproduced on both django 1.5.5 and django 1.6.


'''How to reproduce'''
I have attached an example app to the bug report that does the same.

{{{
1. Have two empty databases in the settings
2. Create a another settings file, which extends 
   the default settings but shuffles the installed apps
3. Run the following commands

$ python manage.py syncdb --database=default --noinput
 
# Settings.other has installed apps in a different order.
$ python manage.py syncdb --database=other --noinput --settings=settings.other
 
# Create a problematic user: (python manage.py shell --database=default)
from django.contrib.auth.models import User, Permission
user, created = User.objects.get_or_create(username='test_usr', is_staff=True, password='abcd')
for permission in Permission.objects.all():
    user.user_permissions.add(permission)
 
# Dump data from the original database
python manage.py dumpdata auth.User --indent=2 --database=default --natural > users.json
 
# Load it to the other database
python manage.py loaddata --database=other --trace users.json

# Results in ""Permission matching query does not exist"" since 
the contenttype id is from the default.

}}}

'''MonkeyPatch:'''

{{{#!python
from django.contrib.auth import models as auth_models
from django.contrib.contenttypes.models import ContentType

def patched_get_by_natural_key(self, codename, app_label, model):
    return self.get(
        codename=codename,
        content_type=ContentType.objects.db_manager(self.db).get_by_natural_key(app_label, model),
    )
auth_models.PermissionManager.get_by_natural_key = patched_get_by_natural_key
}}}

"	Bug	closed	contrib.auth	1.6	Normal	fixed	auth contenttype natural_keys user permissions natural keys multiple databases		Accepted	1	0	0	0	0	0
