Open ad-m opened 4 years ago
W jednym ze swoich projektów używałem czegoś takiego, można by to troche zmodyfikować aby zwracać django.db.models.Q
?
class FilterMixin:
filter_model = None
filter_params = {}
def get_filter_params(self):
filter_params = {}
for k, v in self.filter_params.items():
param = self.request.GET.get(k)
if param:
filter_params[v] = param
return filter_params
def get_queryset(self):
filter_params = self.get_filter_params()
return self.filter_model.objects.filter(**filter_params)
class CollectionViewSet(FilterMixin, ModelViewSet):
serializer_class = CollectionSerializer
filter_model = Collection
filter_params = {
'name': 'name__iexact',
}
Znam django-filter. W jaki sposób wówczas przechowywalibyśmy to w bazie danych? Zastanawiałem się (zob. bebfd619236f692f84e67b9f8e6c1c02c70cac4b ) nad obiektem, ale stwierdziłem, że tekst długoterminowo jest lepszym rozwiązaniem, chociaż wymaga pewnego nakładu pracy, bo pozwoli zbudować bardziej dogodne zapytania z AND
i OR
, ale możemy zacząć od czegoś prostszego.
Niby można trzymać querystring, ale czy to jest czyste rozwiązanie i odpowiednie długoterminowo? Jeżeli nie będziemy wspierać AND
i OR
to nie potrzebujemy models.Q
.
Przeglądając materiały na temat Poradni z @AgnieszkaZdanowicz dostrzegłem https://github.com/ivelum/djangoql , które wydaje się dość ciekawe. Biblioteka utrzymywana przez lata ( https://pypi.org/project/djangoql/#history ).
Niepokoi mnie trochę uwiązanie do struktury modelu Django, ale jednocześnie doceniam duży zakres funkcjonalności.
Powszechna jest składnia Lucene, którą wykorzystuje Elasticsearch. Parser dla niej jest dostępny na https://github.com/pyparsing/pyparsing/blob/master/examples/lucene_grammar.py . Zatem różne podejścia do parsowania mamy. Teraz trzeba by dokładnie zastanowić się jak takie zapytania mają wyglądać i jak mają się przełożyć na SQL.
Na Slacku zwrócono się do @AgnieszkaZdanowicz z zapytanie:
Czy sądzisz, że będzie Ci wygodni wyszukiwać sprawy poprzez budowanie zapytań podobnie jak jest to dostępne w GitHub? W GitHub jest pole tekstowe, które zawiera specyficzny język zapytań. Dla ułatwienia jego użycia można wybrać opcje filtrowania, co tylko modyfikuje zapytanie. Dzięki temu istnieje zawsze jedna wartość, którą można zapisać, aby zapisać wyniki wyszukiwania jako "Ulubione wyszukiwania", albo - co ważniejsze – kolekcje. Chce się upewnić co sądzisz o pomyśle.
@AgnieszkaZdanowicz wskazała:
wydaje mi się to wygodne
Co skłania do tego, aby faktycznie to zapytanie przechowywać w postaci tekstowej. Podsuwa nam także propozycje UI. Jak pokazuje GitHub autocomplete to nie jest jedyna droga budowy takich zapytań, bo można po prostu mieć kontroli UI, które modyfikują odpowiednio zapytanie.
Na ekranie powiadomień GitHub podszedł do problemu w inny sposób: https://github.com/notifications/beta Innowacyjnie i ciekawe.
Zawsze można to skomplikować, ale poszukuje minimalnego zbioru, który będzie użyteczny.
Myślę zatem, że potrzebujemy następujących elementów w składni:
słowa kluczowe
AND
OR
Teraz pomyślę jak zbudować to wspierający parser.
W
Collection
mamy polequery
, które ma zapytanie w postaci tekstowej, które służy do filtrowania spraw w sposób dynamiczny. Ma to na celu sprawienie, abyśmy sformułować wyszukiwanie podobnie do tego co ma GitHub ( https://github.com/issues?q=is%3Aopen+is%3Aissue+author%3Aad-m+archived%3Afalse+label%3Av2 ) i udostępniać sprawy obecne i przyszłe spełniające kryteria wyszukiwania. Z perspektywy deweloperom umożliwi to pobranie spraw należących do kolekcji w sposób podobny do:@mik-laj rekomendował Lark / pyparsing (prostszy) w celu parsowania. Funkcja
parse_query
musi zwracać obiektydjango.db.models.Q
( https://docs.djangoproject.com/en/3.0/topics/db/queries/#complex-lookups-with-q-objects ).