Opened 11 years ago
Closed 11 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 , 11 years ago
| Attachment: | testCase.tar.gz added |
|---|
comment:1 by , 11 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 , 11 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 , 11 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Example app reproducing the issue