Opened 3 years ago

Closed 2 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 3 years ago by anonymous

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

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 3 years ago by rafales

  • Triage Stage changed from Accepted to Design 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 2 years ago by apollo13

  • Resolution set to wontfix
  • Status changed from new to closed

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