Having Trouble Setting Constraints for Fields in a QGIS Layer (using Python API)

88 views Asked by At

I am using Qgis 3.28 Firenze.

I've been trying to set constraints on fields in an empty QGIS layer to control the input when new features are added. Here's a summary of what I'm aiming to achieve:

Ensure certain fields are filled (NotNull constraint + Enforce NotNull). Apply constraints on some fields so that their values lie within a certain range.

I've been working with Python and the QGIS PyQGIS library, but I'm encountering issues getting the constraints to work. I've stored the parameters for each field in a layer in an xlsx.

I can set up the type of the widget of the attribute form, load dropdown list, mark the field if it is editable or not, and assign default value using the code but the part concerning constraints.

Here's the code snippet I've been working with:

import pandas as pd
from qgis.core import QgsProject, QgsFieldConstraints, QgsDefaultValue

# Load the Excel file into a DataFrame
df = pd.read_excel('EXCELPATH.xlsx')

project = QgsProject.instance()

i = 1
for index, row in df.iterrows():
    layer_name = row['LayerName']
    layer = project.mapLayersByName(layer_name)[0] if project.mapLayersByName(layer_name) else None

    if layer:
        field_idx = layer.fields().indexOf(row['FieldName'])

        if field_idx != -1:  # This means there's a matching field in the layer
            print(i, "-", layer.name())   

            
            # CONSTRAINTS
            if 'Constraints/NotNull' in df.columns and 'Constraints/Expression' in df.columns:
                # Initialize constraintsconfig
                constraintsconfig = QgsFieldConstraints()

                # NotNull & Enfoce NotNull
                if row['Constraints/NotNull'] == True:
                    print("NotNull Constraints READ")
                    constraintsconfig.setConstraint(QgsFieldConstraints.ConstraintNotNull, QgsFieldConstraints.ConstraintOriginLayer)
                    constraintsconfig.setConstraintStrength(QgsFieldConstraints.ConstraintNotNull, QgsFieldConstraints.ConstraintStrengthHard)

                # Expression & Expression description
                if pd.notna(row['Constraints/Expression']):
                    print("Constraints Expression READ")
                    constraintsconfig.setConstraint(QgsFieldConstraints.ConstraintExpression, QgsFieldConstraints.ConstraintOriginLayer)
                    constraintsconfig.setConstraintStrength(QgsFieldConstraints.ConstraintExpression, QgsFieldConstraints.ConstraintStrengthHard)
                    
                    print("Constraints Expression Description READ")
                    constraintsconfig.setConstraintExpression(row['Constraints/Expression'], row['Constraints/ExpressionDescription'])
                    print(row['FieldName'], "Constraints Applied:", row['Constraints/Expression'], row['Constraints/ExpressionDescription'])

                # Update field constraints for the entire layer
                fields = layer.fields()
                field = fields.field(field_idx)
                print(field.name())
                field.setConstraints(constraintsconfig)
                
            # Update constraints & Commit changes
            layer.updateFields()     

            i=i+1

project.write()

The code runs smoothly without any errors returned but still constraints do not get applied. As you can see in the image all blocks get their parameters set but the constraints. The other parts of the code are all good for General, Widget Type and Defaults.

0

There are 0 answers