Opened 10 years ago
Closed 10 years ago
#22956 closed Bug (fixed)
PermissionManager.get_by_natural_key doesn't fetch ContentType from same DB
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | contrib.auth | Version: | 1.6 |
Severity: | Normal | Keywords: | auth contenttype natural_keys user permissions natural keys multiple databases |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
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:
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
Attachments (1)
Change History (7)
by , 10 years ago
Attachment: | testCase.tar.gz added |
---|
comment:1 by , 10 years ago
Summary: | loaddata user_permissions from db A to B with natural keys → PermissionManager.get_by_natural_key doesn't fetch ContentType from same DB |
---|---|
Triage Stage: | Unreviewed → Accepted |
Fix looks reasonable. Can you add a test?
comment:3 by , 10 years ago
Has patch: | set |
---|---|
Patch needs improvement: | set |
Please uncheck "Patch needs improvement" if you can update the PR per my comments; thanks!
comment:6 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Example app reproducing the issue