Exemple #1
0
class ApiCrudRestController(BaseController, RestController):
    allow_only = predicates.not_anonymous()
    omit_fields = ['user', '_user_id']
    model = None

    def __init__(self):
        super().__init__()
        self.provider = ProviderTypeSelector().get_selector(self.model).get_provider(self.model, hint=db)

        # if not hasattr(self, 'new_form'):
        # class EditForm(EditableForm):
        #         __entity__ = self.model
        #         __omit_fields__ = self.omit_fields
        #
        #     self.edit_form = EditForm(session)
        #
        # register_validators(self, 'post', self.new_form)
        #
        # if not hasattr(self, 'edit_form'):
        #     class NewForm(AddRecordForm):
        #         __entity__ = self.model
        #         __omit_fields__ = self.omit_fields
        #
        #     self.new_form = NewForm(session)
        #
        # register_validators(self, 'put', self.edit_form)

    def _dictify(self, value):
        if self.omit_fields is False:
            return value

        def _dictify(entity):
            if hasattr(entity, '__json__'):
                return entity.__json__()
            else:
                return self.provider.dictify(entity, omit_fields=self.omit_fields)

        if isinstance(value, list):
            # return a generator, we don't want to consume the whole query
            return (_dictify(entity) for entity in value)
        else:
            return _dictify(value)

    def _before(self, *args, **kw):
        pass
        # if request.response_type != 'application/json':
        # abort(406, 'Only JSON requests are supported')

    def _prepare_query(self):
        return db.query(self.model).with_parent(request.identity["user"])

    def _filter_query(self, query, limit=0, offset=0, order_by="", pagesize=10, page=0, filter="", **kw):
        if limit:
            query = query.limit(limit)

        if limit and offset:
            query = query.offset(offset)

        if order_by:
            for col in [col.split("|") for col in order_by.split(";")]:
                field_name = col[0]
                if not hasattr(self.model, field_name):
                    continue
                field = getattr(self.model, field_name)
                if len(col) == 2:
                    strategy = col[1].lower()
                    if strategy == "asc":
                        field = field.asc()
                    if strategy == "desc":
                        field = field.desc()
                query = query.order_by(field)

        # TODO: pagesize=10&page=1
        # TODO: filter={ field: { $gt: value1, $lt: value2 } }

        return query

    @expose('json')
    def get_all(self, **kw):
        """
            model?limit=5
            model?limit=5&offset=2
            model?order_by=amount
            model?order_by=date|desc;amount|desc
            model?pagesize=10&page=1

        :param kw:
        :return:
        """
        query = self._prepare_query(**kw)
        filtered_query = self._filter_query(query, **kw)

        entities = filtered_query.all()

        if entities is None:
            abort(404, 'Not found')

        return {'value_list': self._dictify(entities), 'total_entries': query.count(), 'entries': filtered_query.count()}

    @expose('json')
    def get_one(self, id, **kw):
        entity = self._prepare_query(**kw).filter(self.model.id == id).first()

        if entity is None:
            abort(404, 'Not found')

        return {'value': self._dictify(entity)}

    @expose('json')
    # @registered_validate()
    def post(self, **kw):
        # if request.response_type != 'application/json':
        # abort(406, 'Only JSON requests are supported')

        if request.validation['errors']:
            return "There was an error"

        entity = self.model(**request.json_body)
        entity._user_id = request.identity["user"].id
        db.add(entity)
        db.flush()

        return self.get_one(entity.id, **kw)

    @expose('json')
    # @registered_validate()
    def put(self, id, **kw):
        # if request.response_type != 'application/json':
        # abort(406, 'Only JSON requests are supported')

        entity = self._prepare_query(**kw).filter(self.model.id == id).first()

        if not entity:
            response.status_code = 404
            return {'error': 'no exists'}

        for key, value in request.json_body.items():
            setattr(entity, key, value)

        db.flush()

        return self.get_one(id, **kw)

    @expose('json')
    def post_delete(self, id, **kw):
        self._prepare_query(**kw).filter(self.model.id == id).delete()