Commit 40bf18e7 authored by sarthakmeh's avatar sarthakmeh Committed by Tim Graham
Browse files

Fixed #25058 -- Added GenericRelations with related_query_name to the admin's...

Fixed #25058 -- Added GenericRelations with related_query_name to the admin's delete confirmation page.
parent 12083c5d
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -231,12 +231,9 @@ class Collector(object):
                        field.remote_field.on_delete(self, field, sub_objs, self.using)
            for field in model._meta.virtual_fields:
                if hasattr(field, 'bulk_related_objects'):
                    # Its something like generic foreign key.
                    # It's something like generic foreign key.
                    sub_objs = field.bulk_related_objects(new_objs, self.using)
                    self.collect(sub_objs,
                                 source=model,
                                 source_attr=field.remote_field.related_name,
                                 nullable=True)
                    self.collect(sub_objs, source=model, nullable=True)

    def related_objects(self, related, objs):
        """
+4 −3
Original line number Diff line number Diff line
@@ -24,9 +24,9 @@ from django.utils.six import StringIO
from .models import (
    Actor, AdminOrderedAdminMethod, AdminOrderedCallable, AdminOrderedField,
    AdminOrderedModelMethod, Album, Answer, Article, BarAccount, Book,
    Category, Chapter, ChapterXtra1, Child, ChildOfReferer, Choice, City,
    Collector, Color, Color2, ComplexSortedPerson, CoverLetter, CustomArticle,
    CyclicOne, CyclicTwo, DependentChild, DooHickey, EmptyModel,
    Bookmark, Category, Chapter, ChapterXtra1, Child, ChildOfReferer, Choice,
    City, Collector, Color, Color2, ComplexSortedPerson, CoverLetter,
    CustomArticle, CyclicOne, CyclicTwo, DependentChild, DooHickey, EmptyModel,
    EmptyModelHidden, EmptyModelMixin, EmptyModelVisible, ExplicitlyProvidedPK,
    ExternalSubscriber, Fabric, FancyDoodad, FieldOverridePost,
    FilteredManager, FooAccount, FoodDelivery, FunkyTag, Gadget, Gallery,
@@ -912,6 +912,7 @@ site.register(Villain)
site.register(SuperVillain)
site.register(Plot)
site.register(PlotDetails)
site.register(Bookmark)
site.register(CyclicOne)
site.register(CyclicTwo)
site.register(WorkHour, WorkHourAdmin)
+9 −0
Original line number Diff line number Diff line
@@ -556,6 +556,15 @@ class SuperSecretHideout(models.Model):
        return self.location


@python_2_unicode_compatible
class Bookmark(models.Model):
    name = models.CharField(max_length=60)
    tag = GenericRelation(FunkyTag, related_query_name='bookmark')

    def __str__(self):
        return self.name


@python_2_unicode_compatible
class CyclicOne(models.Model):
    name = models.CharField(max_length=25)
+28 −15
Original line number Diff line number Diff line
@@ -43,21 +43,21 @@ from . import customadmin
from .admin import CityAdmin, site, site2
from .models import (
    Actor, AdminOrderedAdminMethod, AdminOrderedCallable, AdminOrderedField,
    AdminOrderedModelMethod, Answer, Article, BarAccount, Book, Category,
    Chapter, ChapterXtra1, ChapterXtra2, Character, Child, Choice, City,
    Collector, Color, Color2, ComplexSortedPerson, CoverLetter, CustomArticle,
    CyclicOne, CyclicTwo, DooHickey, Employee, EmptyModel, ExternalSubscriber,
    Fabric, FancyDoodad, FieldOverridePost, FilteredManager, FooAccount,
    FoodDelivery, FunkyTag, Gallery, Grommet, Inquisition, Language,
    MainPrepopulated, ModelWithStringPrimaryKey, OtherStory, Paper, Parent,
    ParentWithDependentChildren, Person, Persona, Picture, Pizza, Plot,
    PlotDetails, PluggableSearchPerson, Podcast, Post, PrePopulatedPost, Promo,
    Question, Recommendation, Recommender, RelatedPrepopulated, Report,
    Restaurant, RowLevelChangePermissionModel, SecretHideout, Section,
    ShortMessage, Simple, State, Story, Subscriber, SuperSecretHideout,
    SuperVillain, Telegram, TitleTranslation, Topping, UnchangeableObject,
    UndeletableObject, UnorderedObject, Villain, Vodcast, Whatsit, Widget,
    Worker, WorkHour,
    AdminOrderedModelMethod, Answer, Article, BarAccount, Book, Bookmark,
    Category, Chapter, ChapterXtra1, ChapterXtra2, Character, Child, Choice,
    City, Collector, Color, Color2, ComplexSortedPerson, CoverLetter,
    CustomArticle, CyclicOne, CyclicTwo, DooHickey, Employee, EmptyModel,
    ExternalSubscriber, Fabric, FancyDoodad, FieldOverridePost,
    FilteredManager, FooAccount, FoodDelivery, FunkyTag, Gallery, Grommet,
    Inquisition, Language, MainPrepopulated, ModelWithStringPrimaryKey,
    OtherStory, Paper, Parent, ParentWithDependentChildren, Person, Persona,
    Picture, Pizza, Plot, PlotDetails, PluggableSearchPerson, Podcast, Post,
    PrePopulatedPost, Promo, Question, Recommendation, Recommender,
    RelatedPrepopulated, Report, Restaurant, RowLevelChangePermissionModel,
    SecretHideout, Section, ShortMessage, Simple, State, Story, Subscriber,
    SuperSecretHideout, SuperVillain, Telegram, TitleTranslation, Topping,
    UnchangeableObject, UndeletableObject, UnorderedObject, Villain, Vodcast,
    Whatsit, Widget, Worker, WorkHour,
)


@@ -2232,6 +2232,19 @@ class AdminViewDeletedObjectsTest(TestCase):
        response = self.client.get(reverse('admin:admin_views_plot_delete', args=(plot.pk,)))
        self.assertContains(response, should_contain)

    def test_generic_relations_with_related_query_name(self):
        """
        If a deleted object has GenericForeignKey with
        GenericRelation(related_query_name='...') pointing to it, those objects
        should be listed for deletion.
        """
        bookmark = Bookmark.objects.create(name='djangoproject')
        tag = FunkyTag.objects.create(content_object=bookmark, name='django')
        tag_url = reverse('admin:admin_views_funkytag_change', args=(tag.id,))
        should_contain = '<li>Funky tag: <a href="%s">django' % tag_url
        response = self.client.get(reverse('admin:admin_views_bookmark_delete', args=(bookmark.pk,)))
        self.assertContains(response, should_contain)


@override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'],
    ROOT_URLCONF="admin_views.urls")