9

I'm using django 1.8. I'm displaying a many-to-many field in django admin like this example.

class PurchaseOrder(models.Model):
    product = models.ManyToManyField('Product')
    vendor = models.ForeignKey('VendorProfile')
    dollar_amount = models.FloatField(verbose_name='Price')


class Product(models.Model):
    products = models.CharField(max_length=256)

    def __unicode__(self):
        return self.products

class PurchaseOrderAdmin(admin.ModelAdmin):
    fields = ['product', 'dollar_amount']
    list_display = ('get_products', 'vendor')

    def get_products(self, obj):
        return "\n".join([p.products for p in obj.product.all()])

The problem is that if I display 100 rows per page, it does 100 queries. For foreign keys, there is a magical list_select_related but you cannot put many-to-many fields in there. How can I avoid duplicate queries?

--- update:

I've tried:

def get_queryset(self, request):
    qs = super(PurchaseOrderAdmin, self).get_queryset(request)
    return qs.prefetch_related('products')

It is still doing duplicate queries per row.

max
  • 9,708
  • 15
  • 89
  • 144
  • Try using prefetch_related. It does a separate lookup for each relationship, and does the ‘joining’ in Python. This allows it to prefetch many-to-many and many-to-one objects (https://docs.djangoproject.com/en/1.10/ref/models/querysets/#prefetch-related). Hope this helps. – Dmitry Shilyaev Jan 29 '17 at 14:30
  • 1
    Thanks @DmitryShilyaev Unfortunately it is still doing duplicate queries. – max Jan 30 '17 at 21:32

1 Answers1

0

Do you also need to do a select_related('product') as part of the get_queryset?

Hard to really say since I don't see the model relation

burroughs06
  • 243
  • 2
  • 5