Improve perfs

This commit is contained in:
Gabriel Augendre 2020-06-01 13:44:54 +02:00
parent 69fd9cd77d
commit f4c92e9c65
2 changed files with 52 additions and 14 deletions

View file

@ -1,4 +1,5 @@
from django.contrib import admin, messages from django.contrib import admin, messages
from django.db.models import Prefetch
from import_export import resources, fields from import_export import resources, fields
from import_export.admin import ExportMixin from import_export.admin import ExportMixin
from import_export.widgets import IntegerWidget, DecimalWidget from import_export.widgets import IntegerWidget, DecimalWidget
@ -69,24 +70,33 @@ class LevelAdmin(ExportMixin, admin.ModelAdmin):
list_editable = ['order'] list_editable = ['order']
list_display_links = ['name'] list_display_links = ['name']
def get_queryset(self, request):
return super(LevelAdmin, self).get_queryset(request).prefetch_related(
Prefetch("book_set", to_attr="prefetched_books"))
def non_acquired_book_count(self, obj: Level): def non_acquired_book_count(self, obj: Level):
return obj.non_acquired_book_count return obj.non_acquired_book_count
non_acquired_book_count.short_description = 'Nombre de livres à acheter (hors consommables)' non_acquired_book_count.short_description = 'Nombre de livres à acheter (hors consommables)'
def non_acquired_book_price(self, obj: Level): def non_acquired_book_price(self, obj: Level):
return f'{obj.non_acquired_book_price:.2f}' return f'{obj.non_acquired_book_price:.2f}'
non_acquired_book_price.short_description = 'Coût des livres à acheter (hors consommables)' non_acquired_book_price.short_description = 'Coût des livres à acheter (hors consommables)'
def non_acquired_consumable_count(self, obj: Level): def non_acquired_consumable_count(self, obj: Level):
return obj.non_acquired_consumable_count return obj.non_acquired_consumable_count
non_acquired_consumable_count.short_description = 'Nombre de consommables à acheter' non_acquired_consumable_count.short_description = 'Nombre de consommables à acheter'
def non_acquired_consumable_price(self, obj: Level): def non_acquired_consumable_price(self, obj: Level):
return f'{obj.non_acquired_consumable_price:.2f}' return f'{obj.non_acquired_consumable_price:.2f}'
non_acquired_consumable_price.short_description = 'Coût des consommables à acheter' non_acquired_consumable_price.short_description = 'Coût des consommables à acheter'
def non_acquired_total_price(self, obj: Level): def non_acquired_total_price(self, obj: Level):
return f'{obj.non_acquired_total_price:.2f}' return f'{obj.non_acquired_total_price:.2f}'
non_acquired_total_price.short_description = 'Coût total à acheter' non_acquired_total_price.short_description = 'Coût total à acheter'
@ -126,6 +136,9 @@ class BookAdmin(ExportMixin, admin.ModelAdmin):
] ]
readonly_fields = ['created_at', 'updated_at'] readonly_fields = ['created_at', 'updated_at']
def get_queryset(self, request):
return super(BookAdmin, self).get_queryset(request).select_related("editor", "level", "teacher")
def update_with_decitre(self, request, queryset): def update_with_decitre(self, request, queryset):
for book in queryset: for book in queryset:
try: try:
@ -171,3 +184,6 @@ class SuppliesRequirementAdmin(ExportMixin, admin.ModelAdmin):
list_editable = ['done'] list_editable = ['done']
readonly_fields = ['created_at', 'updated_at'] readonly_fields = ['created_at', 'updated_at']
list_filter = ['done', 'teacher', 'level'] list_filter = ['done', 'teacher', 'level']
def get_queryset(self, request):
return super(SuppliesRequirementAdmin, self).get_queryset(request).select_related("level", "teacher")

View file

@ -127,34 +127,56 @@ class Level(BaseModel):
def __str__(self): def __str__(self):
return self.name return self.name
@property
def non_acquired_consumables(self):
if hasattr(self, "prefetched_books"):
return filter(lambda book: book.consumable and not book.previously_acquired, self.prefetched_books)
return self.book_set.filter(consumable=True, previously_acquired=False)
@property @property
def non_acquired_consumable_count(self): def non_acquired_consumable_count(self):
return self.book_set.filter(consumable=True, previously_acquired=False).count() if hasattr(self, "prefetched_books"):
return len(list(self.non_acquired_consumables))
return self.non_acquired_consumables.count()
@property @property
def non_acquired_consumable_price(self): def non_acquired_consumable_price(self):
price = self.book_set.filter(consumable=True, previously_acquired=False).aggregate(Sum('price')).get('price__sum', 0) if hasattr(self, "prefetched_books"):
if price is None: return sum(map(lambda book: book.price, self.non_acquired_consumables))
return 0 return self.non_acquired_consumables.aggregate(Sum('price')).get(
return price 'price__sum', 0)
@property
def non_acquired_books(self):
if hasattr(self, "prefetched_books"):
return filter(lambda book: not book.consumable and not book.previously_acquired, self.prefetched_books)
return self.book_set.filter(consumable=False, previously_acquired=False)
@property @property
def non_acquired_book_count(self): def non_acquired_book_count(self):
return self.book_set.filter(consumable=False, previously_acquired=False).count() if hasattr(self, "prefetched_books"):
return len(list(self.non_acquired_books))
return self.non_acquired_books.count()
@property @property
def non_acquired_book_price(self): def non_acquired_book_price(self):
price = self.book_set.filter(consumable=False, previously_acquired=False).aggregate(Sum('price')).get('price__sum', 0) if hasattr(self, "prefetched_books"):
if price is None: return sum(map(lambda book: book.price, self.non_acquired_books))
return 0 return self.non_acquired_books.aggregate(Sum('price')).get(
return price 'price__sum', 0)
@property
def non_acquired_items(self):
if hasattr(self, "prefetched_books"):
return filter(lambda book: not book.previously_acquired, self.prefetched_books)
return self.book_set.filter(previously_acquired=False)
@property @property
def non_acquired_total_price(self): def non_acquired_total_price(self):
price = self.book_set.filter(previously_acquired=False).aggregate(Sum('price')).get('price__sum', 0) if hasattr(self, "prefetched_books"):
if price is None: return sum(map(lambda book: book.price, self.non_acquired_items))
return 0 return self.non_acquired_items.aggregate(Sum('price')).get(
return price 'price__sum', 0)
class Editor(BaseModel): class Editor(BaseModel):