Метод __str__ в модели генерирует большое количество дублирующихся запросов в панели администратора django
У меня есть модель Offer
, которая имеет ForeginKey к другой модели Category
. И через эту модель Category
я получаю Brand
, связанный с этой Category
, и передаю его в Offer
на странице администратора. Но это порождает большое количество запросов, когда я использую это поле Brand
в выпадающем фильтре на Offer admin page
.
models.py
class Brand(BaseFields):
name = models.CharField()
...
def __str__(self):
return self.name()
class Category(BaseFields):
name = models.CharField()
brand = models.ForeignKey(
Brand,
on_delete=models.SET_NULL,
null=True,
blank=True,
)
parents = models.ManyToManyField(
'self',
blank=True,
verbose_name='Parent_category',
related_name='children',
symmetrical=False
)
def __str__(self):
return str(self.brand) + '----' + self.name
class Offer(BaseFields):
name = models.CharField()
category = models.ForeignKey(
Category,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='offer',
verbose_name='Related_category'
)
def __str__(self):
return self.name
admin.py
class OfferAdmin(admin.ModelAdmin):
list_select_related = True
list_display = (
'name',
'brand_name',
'category',
'place',
'status'
)
list_editable = ('place', 'status')
list_filter = (
('category__brand', RelatedOnlyDropdownFilter),
('category', RelatedOnlyDropdownFilter),
'status'
)
fields = [
'name',
'description',
'tech_info',
'ctru',
'category',
'place',
'status'
]
autocomplete_fields = ['category']
actions_on_bottom = True
list_per_page = 25
search_fields = ['name']
def get_queryset(self, request):
return super().get_queryset(request).select_related('category', 'category__brand')
@admin.display(description='Brand', ordering='name')
def brand_name(self, obj):
return obj.category.brand.name
Эти два блока являются основной проблемой, как я понимаю
def __str__(self):
return str(self.brand) + '----' + self.name
list_filter = (
('category__brand', RelatedOnlyDropdownFilter),
('category', RelatedOnlyDropdownFilter),
'status'
)
Мне нужно уменьшить количество генерируемых запросов, вычисляя Brand
для всех предложений. Я понимаю, что должен где-то использовать select_related
, но не понимаю, как именно его использовать.
Вам повезло! На сайте Django admim есть метод get_queryset(...)
, который вы можете переопределить в своем ModelAdmin
подклассе:
https://docs.djangoproject.com/en/5.0/ref/contrib/admin/
class YourModelAdmin(admin.ModelAdmin):
def get_queryset(self, request):
return super().get_queryset(request).select_related(...)