def input_form(self): input_form = super(QgisEditTypeValueRelation, self).input_form if self.FilterExpression != '': exp = QgsExpression(self.FilterExpression) filter_expression = { 'expression': exp.expression(), 'referenced_columns': list(exp.referencedColumns()), 'referenced_functions': list(exp.referencedFunctions()) } # For current_values function in filter expression get parameter field fo it if "current_value" in filter_expression['referenced_functions']: groups = re.findall(r'current_value\(\'(.*?)\'\)|(\w+=\w+)', filter_expression['expression']) filter_expression['referencing_fields'] = [ g[0] for g in groups ] else: filter_expression = None # add params for get value input_form['input']['options'].update({ 'key': self.Value, 'value': self.Key, 'usecompleter': True if self.UseCompleter == '1' or self.UseCompleter == 'true' else False, 'layer_id': self.Layer, 'loading': { 'state': None }, 'filter_expression': filter_expression, }) return input_form
def expression_eval(expression_text, project_id=None, qgs_layer_id=None, form_data=None, formatter=0): """Evaluates a QgsExpression and returns the result :param expression_text: The QgsExpression text :type expression_text: str :param project_id: ID of the qdjango project, defaults to None :type project_id: int, optional :param qgs_layer_id: ID of the QGIS Layer, defaults to None :type qgslayer_id: str, optional :param form_data: A dictionary that maps to a GeoJSON representation of the feature currently edited in the form :type form_data: dict, optional :param formatter: Indicate if form_data values contains formatter values or original features value. :type formatter: int, optional """ expression = QgsExpression(expression_text) expression_context = QgsExpressionContext() layer = None for func_name in expression.referencedFunctions(): if func_name in FORBIDDEN_FUNCTIONS: raise ExpressionForbiddenError( _('Function "{}" is not allowed for security reasons!').format( func_name)) for var_name in expression.referencedVariables(): if var_name in FORBIDDEN_VARIABLES: raise ExpressionForbiddenError( _('Variable "{}" is not allowed for security reasons!').format( var_name)) if project_id is not None: try: project = Project.objects.get(pk=project_id) if qgs_layer_id is not None: try: layer = project.layer_set.get(qgs_layer_id=qgs_layer_id) except Layer.DoesNotExist: raise ExpressionLayerError( _('QGIS layer with id "{}" could not be found!'). format(qgs_layer_id)) expression_contex = QgsExpressionContextUtils.globalProjectLayerScopes( layer.qgis_layer) else: expression_contex = QgsExpressionContextUtils.globalScope() expression_context.appendScope( QgsExpressionContextUtils.projectScope( project.qgis_project)) except Project.DoesNotExist: raise ExpressionProjectError( _('QDjango project with id "{}" could not be found!').format( project_id)) else: expression_contex = QgsExpressionContextUtils.globalScope() if form_data is not None: if layer is None: raise ExpressionLayerError( _('A valid QGIS layer is required to process form data!')) try: # Case by formatter # formatter == 1 : get featureid from layer, usually must be used with formatter form_data # formatter == 0 : default behavior if formatter == 0: fields = layer.qgis_layer.fields() form_feature = QgsJsonUtils.stringToFeatureList( json.dumps(form_data), fields, None)[0] # Set attributes manually because QgsJsonUtils does not respect order for k, v in form_data['properties'].items(): form_feature.setAttribute(k, v) else: qgis_feature_request = QgsFeatureRequest() exp = expression_from_server_fids( [form_data['id']], layer.qgis_layer.dataProvider()) qgis_feature_request.combineFilterExpression(exp) form_feature = get_qgis_features(layer.qgis_layer, qgis_feature_request)[0] expression_context.appendScope( QgsExpressionContextUtils.formScope(form_feature)) expression_context.setFeature(form_feature) except: raise ExpressionFormDataError() valid, errors = expression.checkExpression(expression_text, expression_context) if not valid: raise ExpressionParseError(errors) result = expression.evaluate(expression_context) if expression.hasEvalError(): raise ExpressionEvalError(expression.evalErrorString()) return result