Fixed #20777 -- Admin proxy model deletion regression
Added proxy_models tests by Harm Geerts <github@geertswei.nl>.
This commit is contained in:
parent
4668c142dc
commit
3844089edc
|
@ -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)
|
||||
|
|
|
@ -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::
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from .models import TrackerUser, ProxyTrackerUser
|
||||
|
||||
admin.site.register(TrackerUser)
|
||||
admin.site.register(ProxyTrackerUser)
|
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
from django.conf.urls import patterns, include
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^admin/', include(admin.site.urls)),
|
||||
)
|
Loading…
Reference in New Issue