Code

Opened 4 years ago

Last modified 2 years ago

#14887 new New feature

select_related() does not work with Proxy models and multi-table inheritance

Reported by: Ara Anjargolian <ara818@…> Owned by: nobody
Component: Database layer (models, ORM) Version: 1.2
Severity: Normal Keywords: proxy select_related inheritance
Cc: flisky Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Consider the following models

class TumbleItem(models.Model):
    tumblr_id = models.CharField(max_length=64, editable=False, null=True)
    pub_date = models.DateTimeField(default=datetime.datetime.now)
    format = models.CharField(max_length=10, choices=FORMAT_CHOICES, default='html')
    display_status = models.CharField(max_length=10, choices=DISPLAY_STATUS_CHOICES, default='public')
    tags = TaggableManager()

    # this is for magic later and makes doing lookups both easier and lazier.
    content_type = models.ForeignKey(ContentType, editable=False, null=True)
    object_id = models.PositiveIntegerField(db_index=True, editable=False, null=True)
    object = generic.GenericForeignKey(ct_field="content_type", fk_field="object_id")


class Regular(TumbleItem):
    title = models.CharField(max_length=250, blank=True)
    body = models.TextField()


class StoryItem(TumbleItem):
    class Meta:
        proxy = True
        
    def _slug(self):
        '''
        strip out extra punctuation and create a slug
        '''
        slug = ''
        if self.object.title != '':
            slug = base.get_base_term(self.object.title)
        return slug
    slug = property(_slug)

To access data stored in Regular efficiently, a select_related would be useful. While a select_related has the expected behavior when using TumbleItem, using the proxy model StoryItem it breaks. I would expect them to have the exact same behavior. See below

>>> print TumbleItem.objects.select_related('regular').query
SELECT `djumblr_tumbleitem`.`id`, `djumblr_tumbleitem`.`tumblr_id`, `djumblr_tumbleitem`.`pub_date`, `djumblr_tumbleitem`.`format`, `djumblr_tumbleitem`.`display_status`, `djumblr_tumbleitem`.`content_type_id`, `djumblr_tumbleitem`.`object_id`, `djumblr_regular`.`tumbleitem_ptr_id`, `djumblr_regular`.`title`, `djumblr_regular`.`body` FROM `djumblr_tumbleitem` LEFT OUTER JOIN `djumblr_regular` ON (`djumblr_tumbleitem`.`id` = `djumblr_regular`.`tumbleitem_ptr_id`) ORDER BY `djumblr_tumbleitem`.`pub_date` DESC

>>> print StoryItem.objects.select_related('regular').query
SELECT `djumblr_tumbleitem`.`id`, `djumblr_tumbleitem`.`tumblr_id`, `djumblr_tumbleitem`.`pub_date`, `djumblr_tumbleitem`.`format`, `djumblr_tumbleitem`.`display_status`, `djumblr_tumbleitem`.`content_type_id`, `djumblr_tumbleitem`.`object_id` FROM `djumblr_tumbleitem` ORDER BY `djumblr_tumbleitem`.`pub_date` DESC

Attachments (0)

Change History (6)

comment:1 Changed 4 years ago by Ara Anjargolian <ara818@…>

  • Component changed from Uncategorized to Database layer (models, ORM)
  • Keywords proxy select_related inheritance added
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 4 years ago by russellm

  • Triage Stage changed from Unreviewed to Accepted

comment:3 Changed 3 years ago by jaddison

  • Severity set to Normal
  • Type set to New feature

This would be a nice-to-have addition to existing functionality - marking as 'new feature'.

comment:4 Changed 2 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:5 Changed 2 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:6 Changed 2 years ago by flisky

  • Cc flisky added

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as new
The owner will be changed from nobody to anonymous. Next status will be 'assigned'
as The resolution will be set. Next status will be 'closed'
Author


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

 
Note: See TracTickets for help on using tickets.