Code

Opened 6 years ago

Closed 6 years ago

#9317 closed (wontfix)

Return content type of child class when parent passed to ContentType.objects.get_for_model

Reported by: svetlyak40wt Owned by: nobody
Component: Contrib apps Version: 1.0
Severity: Keywords: contenttype
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

There is a problem during inheritance, if I have:

class Parent(models.Model): pass
class Child(Parent): pass
class Child2(Parent): pass

Next create objects of Child and Child2 types.
After that for each of Parent.objects.all() I want to receive it's ContentType. Obviously, that in case of this inheritance, I need to get ContentType of Child or Child2 instead of Parent.

My patch add this 'virtual' behaviour to get_for_model method. Also it includes two unittests for this behaviour.

Attachments (1)

0001-Right-content-type-if-parent-object-if-given-and-ac.patch (2.7 KB) - added by svetlyak40wt 6 years ago.

Download all attachments as: .zip

Change History (2)

comment:1 Changed 6 years ago by mtredinnick

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to wontfix
  • Status changed from new to closed

I'm a strong -1 on this for reasons that have already been discussed a lot on both django-dev and django-users. This is related to why querying a parent model shouldn't automatically cast to the descendent instances (which aren't necessarily children, but could be grand-children or even further removed).

Firstly, get_for_model() returns the content type for the model you pass in. You're trying to change that to return the content type for some other, related model (the instance you pass in *is* a Parent, it's not down-cast to be one of the child types, so the content type is the content type of Parent). For everybody, not just your call.

Secondly, this is a very expensive operation. If a parent model has 3 children, each of which have 3 children of their own, you've just executed at least 12 database lookups (possibly more if there are other OneToOneFields on the models -- you're heavily misusing _collect_related() here). Thirdly, there's the implementation issue that nothing outside the Model class should be using a method starting with an underscore.

There's probably a useful utility set of functions that somebody could build (as a third-party application initially) that does things like descendent content types and down-casting to the right child, automatically looks for a field such as child_type, etc. But those utilities shouldn't initially be targeted at Django's core, since they don't need to modify anything there. Keep in mind the multi-layer, multi-child inheritance situation, since these things start to scale very poorly once you build up any type of significant hierarchy.

So thanks for writing a patch, but this isn't appropriate as a regular use thing in core. There are too many drawbacks.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.