From 692c73c7e2f5a8849cb8857eeb68243f3bd56030 Mon Sep 17 00:00:00 2001 From: Tomas Gavenciak Date: Thu, 21 May 2015 22:18:44 +0200 Subject: [PATCH] Velke optimalizace SQL pouziti v adminu, select_related() --- seminar/admin.py | 49 ++++++++++++++++++++++++++++++++++++++++++++++- seminar/models.py | 15 ++++++++++++--- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/seminar/admin.py b/seminar/admin.py index a2a594f7..6b4df8b5 100644 --- a/seminar/admin.py +++ b/seminar/admin.py @@ -21,6 +21,7 @@ class ResitelInline(admin.TabularInline): fields = ['jmeno', 'prijmeni', 'skola', 'mesto', 'rok_maturity', ] readonly_fields = ['jmeno', 'prijmeni', 'skola', 'mesto', 'rok_maturity', ] extra = 0 + def has_add_permission(self, req): return False @@ -29,6 +30,7 @@ class CisloInline(admin.TabularInline): fields = ['cislo', 'datum_vydani', 'datum_deadline', 'verejne_db', 'poznamka'] readonly_fields = ['cislo'] extra = 0 + def has_add_permission(self, req): return False @@ -36,6 +38,7 @@ class PrilohaReseniInline(admin.StackedInline): model = PrilohaReseni fields = ['timestamp', 'soubor', 'poznamka'] readonly_fields = ['timestamp'] + extra = 0 @@ -46,14 +49,39 @@ class ReseniKProblemuInline(admin.TabularInline): readonly_fields = ['timestamp'] extra = 0 + def get_queryset(self, request): + qs = super(ReseniKProblemuInline, self).get_queryset(request) + return qs.select_related('problem', 'cislo_body', 'resitel') + + # Potenciální DB HOG (cislo_body se dotazovalo na cisla pri kazdem zobrazeni jejich selectu ...) + def formfield_for_dbfield(self, db_field, **kwargs): + formfield = super(ReseniKProblemuInline, self).formfield_for_dbfield(db_field, **kwargs) + if db_field.name == 'cislo_body': + # dirty trick so queryset is evaluated and cached in .choices + formfield.choices = formfield.choices + return formfield + class ReseniKResiteliInline(admin.TabularInline): model = Reseni fields = ['problem', 'forma', 'body', 'cislo_body', 'timestamp', 'poznamka'] readonly_fields = ['timestamp', 'problem'] extra = 0 + def has_add_permission(self, req): return False + def get_queryset(self, request): + qs = super(ReseniKResiteliInline, self).get_queryset(request) + return qs.select_related('problem', 'cislo_body', 'resitel') + + # Potenciální DB HOG (cislo_body se dotazovalo na cisla pri kazdem zobrazeni jejich selectu ...) + def formfield_for_dbfield(self, db_field, **kwargs): + formfield = super(ReseniKResiteliInline, self).formfield_for_dbfield(db_field, **kwargs) + if db_field.name == 'cislo_body': + # dirty trick so queryset is evaluated and cached in .choices + formfield.choices = formfield.choices + return formfield + class Soustredeni_UcastniciInline(admin.TabularInline): form = autocomplete_light.modelform_factory(Soustredeni_Ucastnici, autocomplete_fields=['resitel'], fields=['resitel']) @@ -78,6 +106,10 @@ class ResitelAdmin(reversion.VersionAdmin): search_fields = ['jmeno', 'prijmeni', 'ulice', 'user', 'mesto', 'email'] inlines = [ReseniKResiteliInline] + def get_queryset(self, request): + qs = super(ResitelAdmin, self).get_queryset(request) + return qs.select_related('skola', 'user') + admin.site.register(Resitel, ResitelAdmin) @@ -108,6 +140,9 @@ class CisloAdmin(reversion.VersionAdmin): list_display = ['kod', 'rocnik', 'cislo', 'datum_vydani', 'datum_deadline', 'verejne'] list_filter = ['rocnik'] view_on_site = Cislo.verejne_url + def get_queryset(self, request): + qs = super(CisloAdmin, self).get_queryset(request) + return qs.select_related('rocnik') admin.site.register(Cislo, CisloAdmin) @@ -149,20 +184,27 @@ class ReseniAdmin(reversion.VersionAdmin): (u'Poznámky', {'fields': ['poznamka']}), ] readonly_fields = ['timestamp'] - list_display = ['problem', 'resitel', 'forma', 'body', 'timestamp'] + list_display = ['problem', 'resitel', 'forma', 'body', 'timestamp', 'cislo_body'] list_filter = ['body', 'timestamp', 'forma'] search_fields = [] inlines = [PrilohaReseniInline] + def get_queryset(self, request): + qs = super(ReseniAdmin, self).get_queryset(request) + return qs.select_related('resitel', 'problem', 'cislo_body') + admin.site.register(Reseni, ReseniAdmin) ### Problem +from autocomplete_light.contrib.taggit_field import TaggitField, TaggitWidget + #TODO: Autocomplete autor/opravovatel class ProblemAdminForm(forms.ModelForm): text_problemu = forms.CharField(widget=CKEditorWidget()) text_problemu_org = forms.CharField(widget=CKEditorWidget()) + zamereni = TaggitField(widget=TaggitWidget('TagAutocomplete')) class Meta: model = Problem exclude = [] @@ -182,6 +224,11 @@ class ProblemAdmin(reversion.VersionAdmin): inlines = [ReseniKProblemuInline] view_on_site = Problem.verejne_url + def get_queryset(self, request): + qs = super(ProblemAdmin, self).get_queryset(request) + return qs.select_related('autor', 'opravovatel', 'cislo_zadani', 'cislo_reseni') + + admin.site.register(Problem, ProblemAdmin) diff --git a/seminar/models.py b/seminar/models.py index d9997e03..3f5f59fd 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -54,6 +54,7 @@ class Skola(SeminarModelBase): db_table = 'seminar_skoly' verbose_name = u'Škola' verbose_name_plural = u'Školy' + ordering = ['mesto', 'nazev'] # Interní ID id = models.AutoField(primary_key = True) @@ -238,7 +239,7 @@ class Cislo(SeminarModelBase): db_table = 'seminar_cisla' verbose_name = u'Číslo' verbose_name_plural = u'Čísla' - ordering = ['rocnik__rocnik', 'cislo'] + ordering = ['rocnik_id', 'cislo'] # Interní ID id = models.AutoField(primary_key = True) @@ -264,7 +265,9 @@ class Cislo(SeminarModelBase): kod.short_description = u'Kód čísla' def __str__(self): - return force_unicode(u'%s' % (self.kod(),)) + #TODO: DB HOG + #return force_unicode(u'%s' % (self.kod(),)) + return force_unicode(u'%s' % (self.cislo,)) def verejne(self): return self.verejne_db @@ -297,6 +300,7 @@ class Problem(SeminarModelBase): db_table = 'seminar_problemy' verbose_name = u'Problém' verbose_name_plural = u'Problémy' + ordering = ['nazev'] # Interní ID id = models.AutoField(primary_key = True) @@ -382,7 +386,7 @@ class Reseni(SeminarModelBase): db_table = 'seminar_reseni' verbose_name = u'Řešení' verbose_name_plural = u'Řešení' - ordering = ['problem', 'resitel'] + ordering = ['problem_id', 'resitel_id'] # Interní ID id = models.AutoField(primary_key = True) @@ -412,6 +416,7 @@ class Reseni(SeminarModelBase): def __str__(self): return force_unicode(u"%s: %s (%sb)" % (self.resitel.plne_jmeno(), self.problem.nazev, self.body)) + #TODO: DB HOG # PrilohaReseni method @@ -511,6 +516,7 @@ class Soustredeni_Ucastnici(models.Model): def __str__(self): return force_unicode(u'%s na %s' % (self.resitel, self.soustredeni, )) + #TODO: DB HOG @python_2_unicode_compatible @@ -533,6 +539,7 @@ class VysledkyBase(SeminarModelBase): def __str__(self): return force_unicode(u"%s: %sb (%s)" % (self.resitel.plne_jmeno(), self.body, str(self.cislo))) + #NOTE: DB HOG (ale nepouzivany) @python_2_unicode_compatible class VysledkyZaCislo(VysledkyBase): @@ -543,6 +550,7 @@ class VysledkyZaCislo(VysledkyBase): managed = False def __str__(self): + #NOTE: DB HOG (ale nepouzivany) return force_unicode(u"%s: %sb (za %s)" % (self.resitel.plne_jmeno(), self.body, str(self.cislo))) @@ -557,6 +565,7 @@ class VysledkyKCislu(VysledkyBase): body_celkem = models.IntegerField(u'body celkem do čísla', db_column='body_celkem') def __str__(self): + #NOTE: DB HOG (ale nepouzivany) return force_unicode(u"%s: %sb / %sb (do %s)" % (self.resitel.plne_jmeno(), self.body, self.body_celkem, str(self.cislo)))