Potrebujem načítať údaje z viacerých tabuliek s dynamicky vytvoreným filtrom, ktorý môže alebo nemusí používať údaje z ktorejkoľvek tabuľky.
Povedzme, že mám toto:
class Solution(models.Model):
name = models.CharField(max_length=MAX, unique=True)
# Other data
class ExportTrackingRecord(models.Model):
tracked_id = models.IntegerField()
solution = models.ForeignKey(Solution)
# Other data
Potom musím urobiť niečo iné:
def get_data(user_provided_criteria):
etr = ExportTrackingRecord.objects.filter(make_Q_object(user_provided_criteria)).select_related()
for data in etr:
s = data.solution
# do things with data from both tables
Pokiaľ môžem povedať, že keď sa stane, že filtrujem na poli v riešení, django urobí spojenie a select_related
získať oba objekty. Ak filtrujem iba na poliach v ExportTrackingRecord
potom tam nebude žiadne spojenie a django vygeneruje nový dotaz pre každého ExportTrackingRecord
v službe QuerySet (ktorá môže byť tisíce ...)
Som celkom nový django, ale existuje rozumný spôsob, ako prinútiť spojenie?
odpovede:
1 pre odpoveď č. 1select_related()
je kľúčom k vášmu problému. Ak ho nepoužijete a nebudete ho filtrovať na poliach príbuzného modelu, Django neuskutoční spojenie a spôsobí dodatočný dopyt pre každý riadok vo výsledku, ak pristupujete k údajom príslušného modelu.
Ak niečo urobíte ExportTrackingRecord.objects.filter(...).select_related("solution")
prinútite Django, aby sa vždy spojil s Solution
stôl.
Ak potrebujete urobiť to isté v opačnom smere, prostredníctvom reverznej zahraničný kľúč vzťah, ktorý potrebujete prefetch_related()
, to isté platí pre vzťahy medzi mnohými až mnohými
0 pre odpoveď č. 2
select_related
kontroluje, čo sa načíta do výsledkov, keď sa vyhodnotí QuerySet. vynúti spojenie bez ohľadu na filtrovanie.
Ak to neurčíte select_related
, potom aj keď váš filter vytvorí dotaz typu sql so spojením, polia rodičovského modelu nebudú načítané do výsledkov a prístup k nim bude vyžadovať ďalšie dotazy.