Kaydet (Commit) 3844089e authored tarafından Anssi Kääriäinen's avatar Anssi Kääriäinen

Fixed #20777 -- Admin proxy model deletion regression

Added proxy_models tests by Harm Geerts <github@geertswei.nl>.
üst 4668c142
...@@ -155,9 +155,6 @@ class NestedObjects(Collector): ...@@ -155,9 +155,6 @@ class NestedObjects(Collector):
if source_attr: if source_attr:
self.add_edge(getattr(obj, source_attr), obj) self.add_edge(getattr(obj, source_attr), obj)
else: 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) self.add_edge(None, obj)
try: try:
return super(NestedObjects, self).collect(objs, source_attr=source_attr, **kwargs) return super(NestedObjects, self).collect(objs, source_attr=source_attr, **kwargs)
......
...@@ -500,9 +500,9 @@ using ``__str__()`` like this:: ...@@ -500,9 +500,9 @@ using ``__str__()`` like this::
.. method:: Model.__eq__() .. method:: Model.__eq__()
The equality method is defined such that instances with the same primary The equality method is defined such that instances with the same primary
key value and the same concrete class are considered equal. The term key value and the same concrete class are considered equal. For proxy
concrete class means proxy model's first non-proxy parent or the class models, concrete class is defined as the model's first non-proxy parent;
itself if it isn't a proxy class. for all other models it is simply the model's class.
For example:: For example::
......
from django.contrib import admin
from .models import TrackerUser, ProxyTrackerUser
admin.site.register(TrackerUser)
admin.site.register(ProxyTrackerUser)
[ [
{
"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, "pk": 100,
"model": "proxy_models.BaseUser", "model": "proxy_models.BaseUser",
...@@ -21,4 +39,4 @@ ...@@ -21,4 +39,4 @@
"assignee": 100 "assignee": 100
} }
} }
] ]
\ No newline at end of file
...@@ -117,9 +117,13 @@ class StateProxy(State): ...@@ -117,9 +117,13 @@ class StateProxy(State):
# Proxy models still works with filters (on related fields) # Proxy models still works with filters (on related fields)
# and select_related, even when mixed with model inheritance # and select_related, even when mixed with model inheritance
@python_2_unicode_compatible
class BaseUser(models.Model): class BaseUser(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
def __str__(self):
return ':'.join((self.__class__.__name__, self.name,))
class TrackerUser(BaseUser): class TrackerUser(BaseUser):
status = models.CharField(max_length=50) status = models.CharField(max_length=50)
...@@ -134,7 +138,7 @@ class Issue(models.Model): ...@@ -134,7 +138,7 @@ class Issue(models.Model):
assignee = models.ForeignKey(TrackerUser) assignee = models.ForeignKey(TrackerUser)
def __str__(self): def __str__(self):
return ':'.join((self.__class__.__name__,self.summary,)) return ':'.join((self.__class__.__name__, self.summary,))
class Bug(Issue): class Bug(Issue):
version = models.CharField(max_length=50) version = models.CharField(max_length=50)
......
...@@ -10,12 +10,14 @@ from django.db import models, DEFAULT_DB_ALIAS ...@@ -10,12 +10,14 @@ from django.db import models, DEFAULT_DB_ALIAS
from django.db.models import signals from django.db.models import signals
from django.db.models.loading import cache from django.db.models.loading import cache
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings
from .models import (MyPerson, Person, StatusPerson, LowerStatusPerson, from .models import (MyPerson, Person, StatusPerson, LowerStatusPerson,
MyPersonProxy, Abstract, OtherPerson, User, UserProxy, UserProxyProxy, MyPersonProxy, Abstract, OtherPerson, User, UserProxy, UserProxyProxy,
Country, State, StateProxy, TrackerUser, BaseUser, Bug, ProxyTrackerUser, Country, State, StateProxy, TrackerUser, BaseUser, Bug, ProxyTrackerUser,
Improvement, ProxyProxyBug, ProxyBug, ProxyImprovement, Issue) Improvement, ProxyProxyBug, ProxyBug, ProxyImprovement, Issue)
from .admin import admin as force_admin_model_registration
class ProxyModelTests(TestCase): class ProxyModelTests(TestCase):
...@@ -366,8 +368,10 @@ class ProxyModelTests(TestCase): ...@@ -366,8 +368,10 @@ class ProxyModelTests(TestCase):
self.assertEqual(MyPerson(id=100), Person(id=100)) self.assertEqual(MyPerson(id=100), Person(id=100))
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class ProxyModelAdminTests(TestCase): class ProxyModelAdminTests(TestCase):
fixtures = ['myhorses'] fixtures = ['myhorses']
urls = 'proxy_models.urls'
def test_cascade_delete_proxy_model_admin_warning(self): def test_cascade_delete_proxy_model_admin_warning(self):
""" """
...@@ -383,3 +387,26 @@ class ProxyModelAdminTests(TestCase): ...@@ -383,3 +387,26 @@ class ProxyModelAdminTests(TestCase):
self.assertTrue(tracker_user in collector.edges.get(None, ())) self.assertTrue(tracker_user in collector.edges.get(None, ()))
self.assertTrue(base_user in collector.edges.get(None, ())) self.assertTrue(base_user in collector.edges.get(None, ()))
self.assertTrue(issue in collector.edges.get(tracker_user, ())) 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()
from django.conf.urls import patterns, include
from django.contrib import admin
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment