def test_flt_string_field(self): op, term = parse_like_term('index-%s' % str(uuid4().hex)) result = get_flt(Journal.index_at, term, op) expected = Q(**{'%s__%s' % (Journal.index_at.name, op): term}) self.assertEqual(expected.query, result.query)
def test_flt_string_field(self): op, term = parse_like_term('index-%s' % str(uuid4().hex)) result = get_flt(Journal.index_at, term, op) expected = Q(**{'%s__%s' % (Journal.index_at.name, op): term}) self.assertEqual(expected.query, result.query)
def apply(self, query, value): term, data = parse_like_term(value) flt = {} if self.column.name == Contact.id.name: flt = {'%s__%s' % (Contact.user_id.name, term): data} data = Contact.objects().filter(**flt).only('id').first() if data is not None: flt = {self.reference_column.name: data.id} return query.filter(**flt)
def _search(self, query, search_term): op, term = parse_like_term(search_term) criteria = None for field in self._search_fields: flt = get_flt(field, term, op) if criteria is None: criteria = flt else: criteria |= flt return query.filter(criteria)
def _search(self, query, search_term): op, term = parse_like_term(search_term) criteria = None for field in self._search_fields: flt = get_flt(field, term, op) if criteria is None: criteria = flt else: criteria |= flt return query.filter(criteria)
def test_custom_filter_not_like(self): journal = makeOneJournal({'title': 'title-%s' % str(uuid4().hex)}) makeOneIssue({'journal': journal}) column = Issue.journal custom_filter = CustomFilterNotLike(column=column, name=__('Periódico')) result = custom_filter.apply(Issue.objects, journal.title) term, data = parse_like_term(journal.title) journals = Journal.objects.filter(Q(**{'title__not__%s' % term: data})) expected = Issue.objects.filter(Q(**{'%s__in' % column.name: journals})) self.assertListEqual([_ for _ in expected], [_ for _ in result])
def test_flt_search_reference_issue(self): journal = makeOneJournal() issue = makeOneIssue({'journal': journal}) makeOneArticle({'journal': journal, 'issue': issue}) op, term = parse_like_term(issue.label) result = get_flt(Article.issue, term, op) issues = Issue.objects.filter(Q(**{'label__%s' % op: term})) expected = Q(**{'issue__in': issues}) self.assertIn('issue__in', result.query) self.assertItemsEqual(expected.query['issue__in'], result.query['issue__in'])
def test_custom_filter_not_like(self): journal = makeOneJournal({'title': 'title-%s' % str(uuid4().hex)}) makeOneIssue({'journal': journal}) column = Issue.journal custom_filter = CustomFilterNotLike(column=column, name=__(u'Periódico')) result = custom_filter.apply(Issue.objects, journal.title) term, data = parse_like_term(journal.title) journals = Journal.objects.filter(Q(**{'title__not__%s' % term: data})) expected = Issue.objects.filter(Q(**{'%s__in' % column.name: journals})) self.assertItemsEqual(expected, result)
def test_flt_search_reference_issue(self): journal = makeOneJournal() issue = makeOneIssue({'journal': journal}) makeOneArticle({'journal': journal, 'issue': issue}) op, term = parse_like_term(issue.label) result = get_flt(Article.issue, term, op) issues = Issue.objects.filter(Q(**{'label__%s' % op: term})) expected = Q(**{'issue__in': issues}) self.assertIn('issue__in', result.query) self.assertListEqual([_ for _ in expected.query['issue__in']], [_ for _ in result.query['issue__in']])
def test_flt_reference_journal(self): journal_fields = { 'title': 'title-%s' % str(uuid4().hex), 'title_iso': 'title_iso-%s' % str(uuid4().hex), 'short_title': 'short_title-%s' % str(uuid4().hex), 'acronym': 'acronym-%s' % str(uuid4().hex), 'print_issn': 'print_issn-%s' % str(uuid4().hex), 'eletronic_issn': 'eletronic_issn-%s' % str(uuid4().hex)} journal = makeOneJournal(journal_fields) makeOneIssue({'journal': journal}) for field in journal_fields: op, term = parse_like_term(journal[field]) result = get_flt(Issue.journal, term, op) journals = Journal.objects.filter(Q(**{'%s__%s' % (field, op): term})) expected = Q(**{'journal__in': journals}) self.assertIn('journal__in', result.query) self.assertItemsEqual(expected.query['journal__in'], result.query['journal__in'])
def test_flt_reference_journal(self): journal_fields = { 'title': 'title-%s' % str(uuid4().hex), 'title_iso': 'title_iso-%s' % str(uuid4().hex), 'short_title': 'short_title-%s' % str(uuid4().hex), 'acronym': 'acronym-%s' % str(uuid4().hex), 'print_issn': 'print_issn-%s' % str(uuid4().hex), 'eletronic_issn': 'eletronic_issn-%s' % str(uuid4().hex)} journal = makeOneJournal(journal_fields) makeOneIssue({'journal': journal}) for field in journal_fields: op, term = parse_like_term(journal[field]) result = get_flt(Issue.journal, term, op) journals = Journal.objects.filter(Q(**{'%s__%s' % (field, op): term})) expected = Q(**{'journal__in': journals}) self.assertIn('journal__in', result.query) self.assertListEqual([_ for _ in expected.query['journal__in']], [_ for _ in result.query['journal__in']])
def apply(self, query, value): term, data = parse_like_term(value) flt = get_flt(self.column, data, 'not__%s' % term) return query.filter(flt)
def test_flt_list_field(self): op, term = parse_like_term('title-%s' % str(uuid4().hex)) result = get_flt(Journal.title, term, op) self.assertIsNotNone(result)
def _search(self, query, search_term): """ Improved search between words. The original _search for MongoEngine dates back to November 12th, 2013 [1]_. In this ref it's stated that there is a bug with complex Q queries preventing multi-word searches. During this time, the MongoEngine version was earlier than 0.4 (predating PyPI) [2]_. Since then, there have been multiple releases [3]_ which appear to have fixed the query issue. Treats id (_id) impliticly as a member of column_searchable_list, except it's not computed in an OR/AND, a direct lookup is checked for. References ---------- .. [1] Search for MongoEngine. 02b936b. November 23, 2013. https://git.io/fxf8C. Accessed September, 29th, 2018. .. [2] MongoEngine releases on PyPI. https://pypi.org/project/mongoengine/#history. Accessed September 29th, 2018. .. [3] MongoEngine release notes. http://docs.mongoengine.org/changelog.html. Accessed September 29th, 2018. """ criterias = mongoengine.Q() rel_criterias = mongoengine.Q() terms = shlex.split(search_term) # If an ObjectId pattern, see if we can get an instant lookup. if len(terms) == 1 and re.match(RE_OBJECTID, terms[0]): q = query.filter(id=bson.ObjectId(terms[0])) if q.count() == 1: # Note: .get doesn't work, they need a QuerySet return q for term in terms: op, term = parse_like_term(term) # Case insensitive by default if op == 'contains': op = 'icontains' criteria = mongoengine.Q() for field in self._search_fields: if isinstance(field, mongoengine.fields.ReferenceField): rel_model = field.document_type rel_fields = ( getattr(self, 'column_searchable_refs', {}) .get(field.name, {}) .get('fields', ['id']) ) # If term isn't an ID, don't do an ID lookup if rel_fields == ['id'] and not re.match(RE_OBJECTID, term): continue ids = [ o.id for o in search_relative_field(rel_model, rel_fields, term) ] rel_criterias |= mongoengine.Q(**{'%s__in' % field.name: ids}) elif isinstance(field, mongoengine.fields.ListField): if not isinstance(field.field, mongoengine.fields.ReferenceField): continue # todo: support lists of other types rel_model = field.field.document_type_obj rel_fields = ( getattr(self, 'column_searchable_refs', {}) .get(field.name, {}) .get('fields', 'id') ) ids = [ o.id for o in search_relative_field(rel_model, rel_fields, term) ] rel_criterias |= mongoengine.Q(**{'%s__in' % field.name: ids}) else: flt = {'%s__%s' % (field.name, op): term} q = mongoengine.Q(**flt) criteria |= q criterias &= criteria # import pprint # pp = pprint.PrettyPrinter(indent=4).pprint # print(pp(query.filter(criterias)._query)) return query.filter(criterias | rel_criterias)
def test_flt_list_field(self): op, term = parse_like_term('title-%s' % str(uuid4().hex)) result = get_flt(Journal.title, term, op)