Fixed #20777 -- Admin proxy model deletion regression

Added proxy_models tests by Harm Geerts <github@geertswei.nl>.
This commit is contained in:
Anssi Kääriäinen 2013-08-15 10:32:54 +03:00
parent 4668c142dc
commit 3844089edc
7 changed files with 67 additions and 8 deletions

View File

@ -155,9 +155,6 @@ class NestedObjects(Collector):
if source_attr:
self.add_edge(getattr(obj, source_attr), obj)
else:
if obj._meta.proxy:
# Take concrete model's instance to avoid mismatch in edges
obj = obj._meta.concrete_model(pk=obj.pk)
self.add_edge(None, obj)
try:
return super(NestedObjects, self).collect(objs, source_attr=source_attr, **kwargs)

View File

@ -500,9 +500,9 @@ using ``__str__()`` like this::
.. method:: Model.__eq__()
The equality method is defined such that instances with the same primary
key value and the same concrete class are considered equal. The term
concrete class means proxy model's first non-proxy parent or the class
itself if it isn't a proxy class.
key value and the same concrete class are considered equal. For proxy
models, concrete class is defined as the model's first non-proxy parent;
for all other models it is simply the model's class.
For example::

View File

@ -0,0 +1,6 @@
from django.contrib import admin
from .models import TrackerUser, ProxyTrackerUser
admin.site.register(TrackerUser)
admin.site.register(ProxyTrackerUser)

View File

@ -1,4 +1,22 @@
[
{
"pk": 100,
"model": "auth.user",
"fields": {
"username": "super",
"first_name": "Super",
"last_name": "User",
"is_active": true,
"is_superuser": true,
"is_staff": true,
"last_login": "2007-05-30 13:20:10",
"groups": [],
"user_permissions": [],
"password": "sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158",
"email": "super@example.com",
"date_joined": "2007-05-30 13:20:10"
}
},
{
"pk": 100,
"model": "proxy_models.BaseUser",
@ -21,4 +39,4 @@
"assignee": 100
}
}
]
]

View File

@ -117,9 +117,13 @@ class StateProxy(State):
# Proxy models still works with filters (on related fields)
# and select_related, even when mixed with model inheritance
@python_2_unicode_compatible
class BaseUser(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return ':'.join((self.__class__.__name__, self.name,))
class TrackerUser(BaseUser):
status = models.CharField(max_length=50)
@ -134,7 +138,7 @@ class Issue(models.Model):
assignee = models.ForeignKey(TrackerUser)
def __str__(self):
return ':'.join((self.__class__.__name__,self.summary,))
return ':'.join((self.__class__.__name__, self.summary,))
class Bug(Issue):
version = models.CharField(max_length=50)

View File

@ -10,12 +10,14 @@ from django.db import models, DEFAULT_DB_ALIAS
from django.db.models import signals
from django.db.models.loading import cache
from django.test import TestCase
from django.test.utils import override_settings
from .models import (MyPerson, Person, StatusPerson, LowerStatusPerson,
MyPersonProxy, Abstract, OtherPerson, User, UserProxy, UserProxyProxy,
Country, State, StateProxy, TrackerUser, BaseUser, Bug, ProxyTrackerUser,
Improvement, ProxyProxyBug, ProxyBug, ProxyImprovement, Issue)
from .admin import admin as force_admin_model_registration
class ProxyModelTests(TestCase):
@ -366,8 +368,10 @@ class ProxyModelTests(TestCase):
self.assertEqual(MyPerson(id=100), Person(id=100))
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class ProxyModelAdminTests(TestCase):
fixtures = ['myhorses']
urls = 'proxy_models.urls'
def test_cascade_delete_proxy_model_admin_warning(self):
"""
@ -383,3 +387,26 @@ class ProxyModelAdminTests(TestCase):
self.assertTrue(tracker_user in collector.edges.get(None, ()))
self.assertTrue(base_user in collector.edges.get(None, ()))
self.assertTrue(issue in collector.edges.get(tracker_user, ()))
def test_delete_str_in_model_admin(self):
"""
Test if the admin delete page shows the correct string representation
for a proxy model.
"""
user = TrackerUser.objects.get(name='Django Pony')
proxy = ProxyTrackerUser.objects.get(name='Django Pony')
user_str = (
'Tracker user: <a href="/admin/proxy_models/trackeruser/%s/">%s</a>' % (user.pk, user))
proxy_str = (
'Proxy tracker user: <a href="/admin/proxy_models/proxytrackeruser/%s/">%s</a>' %
(proxy.pk, proxy))
self.client.login(username='super', password='secret')
response = self.client.get('/admin/proxy_models/trackeruser/%s/delete/' % (user.pk,))
delete_str = response.context['deleted_objects'][0]
self.assertEqual(delete_str, user_str)
response = self.client.get('/admin/proxy_models/proxytrackeruser/%s/delete/' % (proxy.pk,))
delete_str = response.context['deleted_objects'][0]
self.assertEqual(delete_str, proxy_str)
self.client.logout()

View File

@ -0,0 +1,7 @@
from django.conf.urls import patterns, include
from django.contrib import admin
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
)