Opened 4 years ago

Closed 4 years ago

#19624 closed Cleanup/optimization (wontfix)

Generic Detail View context contains object twice.

Reported by: mail@… Owned by: nobody
Component: Generic views Version: 1.5-beta-1
Severity: Normal Keywords: generic view
Cc: Triage Stage: Design decision needed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The (simplified and commented) code excerpt below, taken from django/views/generic/detail.py shows that the object is put into context twice, under different keywords. Is this intentional?

The whole construction is most certainly not elegant and makes inheriting from SingleObjectMixin somewhat cumbersome as I have to explicitely set self.object if I don't have BaseDetailView in my class inheritance or override BaseDetailView.get()

class SingleObjectMixin(ContextMixin):
    def get_context_data(self, **kwargs):
        # this puts self.object into context under keyword context_object_name
        context[context_object_name] = self.object
        context.update(kwargs)
        return super(SingleObjectMixin, self).get_context_data(**context)

class BaseDetailView(SingleObjectMixin, View):
    def get(self, request, *args, **kwargs):
        # this puts self.object into context under 'object' --> is this redundancy intentional?
        self.object = self.get_object()
        context = self.get_context_data(object=self.object)
        return self.render_to_response(context)

Change History (3)

comment:1 Changed 4 years ago by anonymous

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Triage Stage: UnreviewedAccepted

Setting self.object seems necessary and I don't see that as a problem. Having the same object in the context does seem unnecessary. What about adding a context_object_name attribute by default to BaseDetailView. ei:

class BaseDetailView(SingleObjectMixin, View):
    context_object_name = 'object'

comment:2 Changed 4 years ago by Rafal Stozek

Triage Stage: AcceptedDesign decision needed

-1 on this.

This is more complicated than just "object" or context_object_name. By default views add "modelname" or "modelnames_list" to context. context_object_name can alter this behaviour:

    def get_context_object_name(self, obj):
        """
        Get the name to use for the object.
        """
        if self.context_object_name:
            return self.context_object_name
        elif isinstance(obj, models.Model):
            return obj._meta.object_name.lower()
        else:
            return None

This is a known behaviour and often relied upon. That change would cause a lot of compatibility issues with older versions of django.

comment:3 Changed 4 years ago by Florian Apolloner

Resolution: wontfix
Status: newclosed

Yes, this is on purpose, "object" is useful for real generic code, but one often wants to use a more fitting name. I don't see the duplication as an issue.

Note: See TracTickets for help on using tickets.
Back to Top