class ModelDescriptionRelationSerializer(Serializer): name = fields.CharField() related_model = fields.JSONField() field = fields.CharField() related_model_field = fields.CharField() through = fields.JSONField() class Meta: fields = ( 'name', 'related_model', 'field', 'related_model_field', 'through', )
class ModelDescriptionSerializer(Serializer): model = fields.CharField() db_table = fields.CharField() hidden = fields.BooleanField() primary_key_field = fields.CharField() fields = ModelDescriptionFieldSerializer(many=True) relations = ModelDescriptionRelationSerializer(many=True) class Meta: fields = ( 'model', 'db_table', 'hidden', 'fields', 'relations', 'primary_key_field', )
class ModelDescriptionFieldSerializer(Serializer): name = fields.CharField() db_column = fields.CharField() field = fields.CharField() filterable = fields.BooleanField() editable = fields.BooleanField() params = fields.JSONField() class Meta: fields = ( 'name', 'db_column', 'field', 'filterable', 'editable', 'params', )
class SqlSerializer(Serializer): query = fields.CharField() params = SqlParamsSerializers(required=False) class Meta: fields = ( 'query', 'params', ) def validate_query(self, value): forbidden = ['insert', 'update', 'delete', 'grant', 'show'] for i in range(len(forbidden)): forbidden.append('({}'.format(forbidden[i])) if any(map(lambda x: ' {} '.format(value.lower()).find(' {} '.format(x)) != -1, forbidden)): raise ValidationError('forbidden query') i = 0 while value.find('%s') != -1: value = value.replace('%s', ':param_{}'.format(i), 1) i += 1 return value def execute(self, data): session = Session() query = data['query'] params = data.get('params', []) try: result = session.execute( text(query), params ) rows = list(map(lambda x: x.itervalues(), result)) def map_column(x): if x == '?column?': return return x return {'data': rows, 'columns': map(map_column, result.keys())} except (SQLAlchemyError, TypeError) as e: raise SqlError(e) finally: session.close()
class ReorderSerializer(Serializer): ordering_field = fields.CharField() forward = fields.BooleanField() segment_from = fields.IntegerField() segment_to = fields.IntegerField() item = fields.IntegerField() segment_by_ordering_field = fields.BooleanField(default=False) def save(self): mapper = inspect(Model) primary_key_field = mapper.primary_key[0].name ordering_field = self.validated_data['ordering_field'] primary_key = getattr(Model, primary_key_field) ordering = getattr(Model, ordering_field) if self.validated_data.get('segment_by_ordering_field'): segment_from = self.validated_data['segment_from'] segment_to = self.validated_data['segment_to'] else: segment_from_instance = queryset.filter( primary_key == self.validated_data['segment_from']).first() segment_to_instance = queryset.filter( primary_key == self.validated_data['segment_to']).first() segment_from = getattr(segment_from_instance, ordering_field) segment_to = getattr(segment_to_instance, ordering_field) if self.validated_data['forward']: queryset.filter(ordering >= segment_from, ordering <= segment_to).update( {ordering_field: ordering - 1}) queryset.filter( primary_key == self.validated_data['item']).update( {ordering_field: segment_to}) else: queryset.filter(ordering >= segment_from, ordering <= segment_to).update( {ordering_field: ordering + 1}) queryset.filter( primary_key == self.validated_data['item']).update( {ordering_field: segment_to}) session.commit()