def from_search(self, company=None, filters=None): """ Intelligently filter based on query . Inputs: :company: The company to restrict results to :filters: A JSON string which is an object to be passed to filter(). :filters: A dict of field: term pairs where field is a field of the ``ContactRecord`` model and term is search term you'd like to filter against. For ``datetime``, pass ``start_date`` and/or ``end_date`` instead. Example: If you want to filter partners where the related contact record's date time is before a certain date:: Partner.objects.from_search(filters=json.dumps({ 'contactrecord': { 'date_time': { 'lte': '2015-08-03 00:00:00.0' } } }) The above is equivalent to: Partner.objects.filter( contactrecord__date_time__lte='2015-08-03 00:00:00.0') """ # default to an empty object filters = filters or "{}" if company: self = self.filter(**{ getattr(self.model, 'company_ref', 'company'): company}) query = json_to_query(json.loads(filters)) if hasattr(self.model, 'approval_status'): query.update({'approval_status__code__iexact': Status.APPROVED}) self = self.filter(**query).distinct() return self
def backwards(self, orm): """ The old params format didn't explicitly mention the comparison to be performed when running a query, so we need to not only convert from nested JSON to a flat django like query string, but we also need to remove those explicit comparison terms. Report regeneration should only happen after first migrating back t 0005. """ reports = Report.objects.exclude(filters__icontains='__') for report in reports: filters = json_to_query(json.loads(report.filters)) for key, value in filters.items(): if 'locations__state' in key: new_key = 'state' elif 'locations__city' in key: new_key = 'city' elif 'date_time__gte' in key: new_key = 'start_date' elif 'date_time__lte' in key: new_key = 'end_date' elif 'contact__in' in key: new_key = 'contact' elif 'partner__in' in key: new_key = 'partner' else: new_key = reduce( lambda acc, x: acc.split(x)[0], ["__gte", "__icontains", "__iexact", "__lte", "__in"], key) # deal with differences in old and new api filters[new_key] = filters.pop(key) if new_key in ['start_date', 'end_date']: if ' ' in filters[new_key]: y, m, d = filters[new_key].split(' ')[0].split('-') filters[new_key] = '%s/%s/%s' % (m, d, y) report.filters = json.dumps(filters) report.save()
def backwards(self, orm): """ The old params format didn't explicitly mention the comparison to be performed when running a query, so we need to not only convert from nested JSON to a flat django like query string, but we also need to remove those explicit comparison terms. Report regeneration should only happen after first migrating back t 0005. """ reports = Report.objects.exclude(filters__icontains='__') for report in reports: filters = json_to_query(json.loads(report.filters)) for key, value in filters.items(): if 'locations__state' in key: new_key = 'state' elif 'locations__city' in key: new_key = 'city' elif 'date_time__gte' in key: new_key = 'start_date' elif 'date_time__lte' in key: new_key = 'end_date' elif 'contact__in' in key: new_key = 'contact' elif 'partner__in' in key: new_key = 'partner' else: new_key = reduce(lambda acc, x:acc.split(x)[0], [ "__gte", "__icontains", "__iexact", "__lte", "__in" ], key) # deal with differences in old and new api filters[new_key] = filters.pop(key) if new_key in ['start_date', 'end_date']: if ' ' in filters[new_key]: y, m, d = filters[new_key].split(' ')[0].split('-') filters[new_key] = '%s/%s/%s' % (m, d, y) report.filters = json.dumps(filters) report.save()