Jaki jest zalecany idiom do sprawdzania, czy zapytanie zwróciło jakieś wyniki?
Przykład:
orgs = Organisation.objects.filter(name__iexact = 'Fjuk inc')
# If any results
# Do this with the results without querying again.
# Else, do something else...
Przypuszczam, że istnieje kilka różnych sposobów sprawdzenia tego, ale chciałbym wiedzieć, jak zrobiłby to doświadczony użytkownik Django. Większość przykładów w dokumentach po prostu ignoruje przypadek, w którym nic nie znaleziono ...
django
django-queryset
Niklas
źródło
źródło
list
wyniku, jeśli istnieją rekordy. Tam kod trafi do bazy danych tylko raz. Gdyby użyliexist()
lubcount()
najpierw sprawdzili, czy rekordy zostaną zwrócone, uderzyliby dwukrotnie w bazę danych (raz, aby sprawdzić, raz, aby uzyskać rekordy). To jest szczególna sytuacja. Nie oznacza to, że w ogólnym przypadku preferowaną metodą sprawdzenia, czy zapytanie zwróci rekordy, jest użycie doif queryset:...
if not my_objects:
pokazujący, że tak robią to w dokumentach. Wszystko inne jest całkowicie nieistotne, więc nie rozumiem, o co ci chodzi. Równie dobrze mogliby zadać tysiące zapytań i byłoby to zupełnie nieistotne, ponieważ nie o to chodzi w tej odpowiedzi, z którą wyjaśniam, że się zgadzam.get_object_or_404
działa, a nie preferowany sposób sprawdzania, czy w zestawie zapytań istnieją jakieś elementy. Wykonanie list () w zestawie zapytań spowoduje pobranie wszystkich obiektów w zestawie zapytań, co byłoby gorsze niż dwukrotne zapytanie, jeśli zwróci się wiele wierszy..exists()
jest bardziej wydajne, jeśli qs nie będzie poddawany ocenie.Od wersji 1.2 Django ma QuerySet. istnieje () metoda, która jest najbardziej wydajna:
Ale jeśli mimo wszystko zamierzasz ocenić QuerySet, lepiej użyć:
Aby uzyskać więcej informacji, przeczytaj dokumentację QuerySet.exists () .
źródło
.get
nie zwraca zestawu zapytań. Zwraca obiekt. Więc google dla tegoJeśli masz ogromną liczbę obiektów, może to (czasami) być znacznie szybsze:
Nad projektem pracuję z ogromną bazą danych, która
not orgs
ma ponad 400 ms i 250 msorgs.count()
. W moich najczęstszych przypadkach użycia (tych, w których są wyniki), ta technika często sprowadza to do poniżej 20ms. (Znalazłem jeden przypadek, było 6).Może to oczywiście trwać znacznie dłużej, w zależności od tego, jak daleko baza danych musi szukać, aby znaleźć wynik. Lub nawet szybciej, jeśli szybko ją znajdzie; YMMV.
EDYCJA: Często będzie to wolniejsze, niż
orgs.count()
jeśli wynik nie zostanie znaleziony, szczególnie jeśli warunek, na którym filtrujesz, jest rzadki; w rezultacie jest szczególnie przydatny w funkcjach widoku, w których musisz się upewnić, że widok istnieje lub wyrzucić Http404. (Można się spodziewać, że ludzie pytają o adresy URL, które istnieją częściej niż nie).źródło
Aby sprawdzić pustość zestawu zapytań:
lub możesz sprawdzić pierwszy element w zestawie zapytań, jeśli nie istnieje, zwróci
None
:źródło
if orgs.exists()
została objęta odpowiedzią udzieloną około 5 lat wcześniej. Jedyną rzeczą, jaką ta odpowiedź przynosi być może nowemu stołowi, jestif orgs.first()
. (Nawet to jest dyskusyjne: czy zasadniczo różni się to od wykonaniaorgs[0]
sugerowanego również około 5 lat temu?) Należy rozwinąć tę część odpowiedzi: kiedy ktoś chciałby to zrobić zamiast innych proponowanych wcześniej rozwiązań?Najbardziej wydajnym sposobem (przed django 1.2) jest:
źródło
Nie zgadzam się z orzeczeniem
Powinno być
Miałem ten sam problem z dość dużym zestawem wyników (~ 150 000 wyników). Operator nie jest przeciążony w QuerySet, więc wynik jest faktycznie rozpakowywany jako lista przed sprawdzeniem. W moim przypadku czas realizacji skrócił się o trzy zamówienia.
źródło
Możesz także użyć tego:
if(not(orgs)): #if orgs is empty else: #if orgs is not empty
źródło