Já se snažím, aby se zabránilo obscénní množství databázových dotazů v Django aplikace. V aplikaci jsem monotoring řadu návrhů (vzor: Návrh), které mohou být hlasoval pro (model: Hlasování).
Hlasování modelu neukládá každé jednotlivé hlasování. Místo toho celkový počet hlasů pro návrh jsou uloženy v pravidelných intervalech. Návrh "Lepší zmrzlinu," mohl "10 hlasů v 8:10", "12 hlasů v 8:20", "25 hlasů v 8:30", atd.
Vytvořil jsem velmi ineffecient smyčky s velkou n+1 otázek pro výpočet počet nových hlasů za den za návrh.
Hledám účinnější (asi jeden) queryset, než ty současné pro stejné funkce. Vím, že bych měla asi vytvořit nějakou anotaci dat hlasů na "návrhy" v views.py a pak komentovat, že tím, že moje agregované funkce, která počítá počet hlasů na každý den, ale nemůžu přijít na to, jak se vlastně řetězce dohromady.
Tady je můj současný pracovní, ale velmi neefektivní kód:
models.py:
class Suggestion(models.Model):
unique_id = models.CharField(max_length=10, unique=True)
title = models.CharField(max_length=500)
suggested_date = models.DateField()
class Vote(models.Model):
suggestion = models.ForeignKey('Suggestion', on_delete=models.CASCADE)
timestamp = models.DateTimeField()
votes = models.IntegerField()
views.py:
def index(request):
# Proces votes per day per suggestion
suggestions = Suggestion.objects.prefetch_related('vote_set')
votes_per_day_per_suggestion = {}
for suggestion in suggestions:
votes_per_day_per_suggestion[suggestion.title] = {}
votes = suggestion.vote_set
suggestion_dates = votes.dates('timestamp', 'day') # n+1 issue
for date in suggestion_dates:
date_min_max = votes.filter(timestamp__date=date).aggregate(votes_on_date=(Max('votes') - Min('votes'))) # n+1 issue
votes_per_day_per_suggestion[suggestion.title][date] = date_min_max['votes_on_date']
context['votes_per_day_per_suggestion'] = votes_per_day_per_suggestion
return render(request, 'borgerforslag/index.html', context)
Šablona výstup:
Better toilet paper (number of votes per day):
19. october 2021: 23
20. october 2021: 19
21. october 2021: 18
22. october 2021: 9
23. october 2021: 25
24. october 2021: 34
25. october 2021: 216