def update_from_query_string(request, Model, query, adapter): headers = request.response.headers if request.params: # TODO: Implement schema validation to use request.validated querystring = QueryString(request, Model, adapter=adapter) total_query = querystring.from_filter_by(query) total_query = querystring.from_tags(total_query) query = querystring.from_order_by(total_query) query = querystring.from_limit(query) query = querystring.from_offset(query) # TODO: Advanced pagination with Link Header # Link: '<https://api.github.com/user/repos?page=3&per_page=100>; # rel="next", # <https://api.github.com/user/repos?page=50&per_page=100>; # rel="last"' headers['X-Count-Records'] = str(query.count()) headers['X-Total-Records'] = str(total_query.count()) # TODO: Etag / timestamp / 304 if no changes # TODO: Cache headers return query else: # no querystring, returns all records (maybe we will want to apply # some default filters values headers['X-Count-Records'] = str(query.count()) headers['X-Total-Records'] = str(query.count()) return query
def test_querystring_from_offset_without_offset(self, registry_blok): registry = registry_blok request = MockRequest(self) model = registry.System.Blok query = model.query() qs = QueryString(request, model) qs.offset = None Q = qs.from_offset(query) assert len(Q.all()) == len(query.all())
def test_querystring_from_offset_without_offset(self): registry = self.init_registry(None) request = MockRequest(self) model = registry.System.Blok query = model.query() qs = QueryString(request, model) qs.offset = None Q = qs.from_offset(query) self.assertEqual(len(Q.all()), len(query.all()))
def read(cls, request): # check user is disconnected # check user has access rigth to see this resource model = request.params['context[model]'] fields = cls.parse_fields( request.params['context[fields]'], model, request.authenticated_userid, ) # TODO complex case of relationship Model = cls.anyblok.get(model) adapter = Model.get_furetui_adapter() qs = QueryString(request, Model, adapter=adapter) query = cls.anyblok.Pyramid.restrict_query_by_user( qs.Model.query(), request.authenticated_userid) query = qs.from_filter_by(query) query = qs.from_filter_by_primary_keys(query) query = qs.from_composite_filter_by(query) query = qs.from_tags(query) query2 = qs.from_order_by(query) query2 = qs.from_limit(query2) query2 = qs.from_offset(query2) query2 = query2.options(*cls.add_options(deepcopy(fields), model)) data = [] pks = [] def append_result(fields, model_name, entry): model = cls.anyblok.get(model_name) fd = model.fields_description() current_fields = fields.pop("__fields") current_fields.extend(fields.keys()) data.append({ 'type': 'UPDATE_DATA', 'model': model_name, 'pk': entry.to_primary_keys(), 'data': entry.to_dict(*current_fields), }) for field, subfield in fields.items(): children_entries = getattr(entry, field) if children_entries: if fd[field]['type'] in ('Many2One', 'One2One'): children_entries = [children_entries] for child_entry in children_entries: append_result(deepcopy(fields[field]), fd[field]['model'], child_entry) for entry in query2: pks.append(entry.to_primary_keys()) append_result(deepcopy(fields), model, entry) # query.count do a sub query, we do not want it, because mysql # has a terrible support of subqueries # total = query.with_entities(func.count('*')).scalar() total = query.count() return { 'pks': pks, 'total': total, 'data': data, }