5

I have following models:

class UserProfile(models.Model):
  name = models.CharField()
  info = models.OneToOneField(UserInfo, related_name='user')

class UserInfo(models.Model):
  def __unicode__(self):
    return self.user.__unicode__() + self.age
  age = models.IntegerField()

class Ticket(models.Model):
  userinfo = models.ForeignKey(UserInfo)

The problem is now in the Ticket admin interface. Ticket's userinfo field is rendered as dropdown. If there is lots of UserInfo in the database, every one of them makes a single call to the database (UserProfile) to generate its name.

How can I tell the admin (or any widget) to prefetch related UserProfiles when it is rendering the UserInfo dropdown?

I am looking for something like

info = models.OneToOneField(UserInfo, related_name='user', prefetch_in_bulk=True)
Juho Rutila
  • 2,316
  • 1
  • 25
  • 40
  • use `return unicode("{} + {}".format(self.user,self.age))` instead of what you have now (`__unicode__` should return unicode, not strings). – Burhan Khalid Mar 24 '13 at 09:08

1 Answers1

9

I figured out one way to do this:

class TicketAdminForm(forms.ModelForm):
  class Meta:
    model = Ticket
  userinfo = forms.ModelChoiceField(queryset=UserInfo.objects.prefetch_related('user').all())

class TicketAdmin(admin.ModelAdmin):
  form = TicketAdminForm

admin.site.register(Ticket, TicketAdmin)

Now the needed models are prefetched as a one sql query rather than many queries.

Juho Rutila
  • 2,316
  • 1
  • 25
  • 40