Commit f64a3de2 authored by Markus Holtermann's avatar Markus Holtermann
Browse files

[1.8.x] Fixed #24940 -- Made model managers hashable

Thanks Federico Jaramillo Martínez for the report and Tim Graham for the
test and review.

Backport of d3d66d47 from master
parent aa00f482
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -236,6 +236,9 @@ class BaseManager(object):
    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return id(self)


class Manager(BaseManager.from_queryset(QuerySet)):
    pass
+3 −0
Original line number Diff line number Diff line
@@ -74,3 +74,6 @@ Bugfixes

* Fixed crash when uploading images with MIME types that Pillow doesn't detect,
  such as bitmap, in ``forms.ImageField`` (:ticket:`24948`).

* Fixed a regression when deleting a model through the admin that has a
  ``GenericRelation`` with a ``related_query_name`` (:ticket:`24940`).
+1 −1
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ class PhoneNumber(models.Model):

class Contact(models.Model):
    name = models.CharField(max_length=50)
    phone_numbers = GenericRelation(PhoneNumber)
    phone_numbers = GenericRelation(PhoneNumber, related_query_name='phone_numbers')


#
+14 −1
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@ from django.contrib.admin.sites import AdminSite
from django.contrib.auth.models import User
from django.contrib.contenttypes.admin import GenericTabularInline
from django.contrib.contenttypes.forms import generic_inlineformset_factory
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
from django.forms.formsets import DEFAULT_MAX_NUM
from django.forms.models import ModelForm
from django.test import (
@@ -16,7 +18,7 @@ from django.test import (
from django.utils.deprecation import RemovedInDjango19Warning

from .admin import MediaInline, MediaPermanentInline, site as admin_site
from .models import Category, Episode, EpisodePermanent, Media
from .models import Category, Episode, EpisodePermanent, Media, PhoneNumber


# Set DEBUG to True to ensure {% include %} will raise exceptions.
@@ -301,6 +303,17 @@ class GenericInlineAdminWithUniqueTogetherTest(TestCase):
        response = self.client.post('/generic_inline_admin/admin/generic_inline_admin/contact/add/', post_data)
        self.assertEqual(response.status_code, 302)  # redirect somewhere

    def test_delete(self):
        from .models import Contact
        c = Contact.objects.create(name='foo')
        PhoneNumber.objects.create(
            object_id=c.id,
            content_type=ContentType.objects.get_for_model(Contact),
            phone_number="555-555-5555",
        )
        response = self.client.post(reverse('admin:generic_inline_admin_contact_delete', args=[c.pk]))
        self.assertContains(response, 'Are you sure you want to delete')


@override_settings(ROOT_URLCONF="generic_inline_admin.urls")
class NoInlineDeletionTest(TestCase):