Biorąc pod uwagę klasę:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=20)
Czy jest możliwe, a jeśli tak, to w jaki sposób, mieć zestaw QuerySet filtrujący na podstawie dynamicznych argumentów? Na przykład:
# Instead of:
Person.objects.filter(name__startswith='B')
# ... and:
Person.objects.filter(name__endswith='B')
# ... is there some way, given:
filter_by = '{0}__{1}'.format('name', 'startswith')
filter_value = 'B'
# ... that you can run the equivalent of this?
Person.objects.filter(filter_by=filter_value)
# ... which will throw an exception, since `filter_by` is not
# an attribute of `Person`.
python
django
django-models
Brian M. Hunt
źródło
źródło
Uproszczony przykład:
W aplikacji ankietowej Django chciałem mieć listę wyboru HTML pokazującą zarejestrowanych użytkowników. Ale ponieważ mamy 5000 zarejestrowanych użytkowników, potrzebowałem sposobu na filtrowanie tej listy na podstawie kryteriów zapytania (takich jak tylko osoby, które ukończyły określone warsztaty). Aby element ankiety mógł być ponownie użyty, potrzebowałem, aby osoba tworząca pytanie ankietowe mogła dołączyć te kryteria do tego pytania (nie chcę na stałe zakodować zapytania w aplikacji).
Rozwiązanie, które wymyśliłem, nie jest w 100% przyjazne dla użytkownika (wymaga pomocy technika w celu utworzenia zapytania), ale rozwiązuje problem. Podczas tworzenia pytania redaktor może wprowadzić słownik w własne pole, np .:
Ten ciąg jest przechowywany w bazie danych. W kodzie widoku wraca jako
self.question.custom_query
. Wartością tego jest łańcuch, który wygląda jak słownik. Przekształcamy go z powrotem w prawdziwy słownik za pomocą eval (), a następnie umieszczamy go w zestawie zapytań za pomocą ** kwargs:źródło
eval()
importu użytkowników to zły pomysł, nawet jeśli całkowicie ufasz swoim użytkownikom. Lepszym pomysłem byłoby tutaj pole JSON.Django.db.models.Q jest dokładnie tym, czego potrzebujesz w Django.
źródło
Q(**filters)
Jeśli chcesz dynamicznie budować obiekty Q, możesz umieścić je na liście i użyć.filter(*q_objects)
lub użyć operatorów bitowych do połączenia obiektów Q.Naprawdę złożone formularze wyszukiwania zwykle wskazują, że prostszy model próbuje wykopać, z którego się wydostaje.
Jak dokładnie spodziewasz się uzyskać wartości dla nazwy kolumny i operacji? Gdzie można uzyskać wartości ?
'name'
'startswith'
Formularz „wyszukiwania”? Zamierzasz - co? - wybrać nazwisko z listy nazwisk? Wybrać operację z listy operacji? Chociaż otwarte, większość ludzi uważa, że jest to zagmatwane i trudne w użyciu.
Ile kolumn ma takie filtry? 6? 12? 18?
Określone przyciski filtrów. Czekaj ... Tak działa administrator Django. Poszczególne filtry zamieniają się w przyciski. Obowiązuje ta sama analiza, co powyżej. Kilka filtrów ma sens. Duża liczba filtrów oznacza zwykle rodzaj pierwszego naruszenia normalnej postaci.
Wiele podobnych pól często oznacza, że powinno być więcej wierszy i mniej pól.
źródło