4

I have a vector layer to which I want to apply some constraints using a script with PyQGIS (a NOT NULL constraint on some fields).

I checked the docs of PyQGIS and found setConstraintExpression (int index, const QString &expression, const QString &description=QString()) which as I understand it from the docs it applies to a QgsVectorLayer I used it in my code like this:

my_layer = QgsVectorLayer('./path/to/my_layer.shp', 'my_layer', 'ogr')
field_index = my_layer.fieldNameIndex('ID')
my_layer.setConstraintExpression(field_index, 'NOT NULL')

I get an error that the function does not exist :

> AttributeError: 'QgsVectorLayer' object has no attribute
> 'setConstraintExpression'

I also tried setFieldConstraint and I get the same error. How can I add a constraint on a field using PyQGIS? (QGIS 2.18 Las Palmas)


I've just noticed that these 2 methods I tried are in the QGIS API 2.99.0-Master which is still not released.

PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Jul 25, 2017 at 7:38

3 Answers 3

3

In QGIS v2.18.x you can use the QgsEditFormConfig class.

Set a Not Null constraint:

formConfig = layer.editFormConfig()
formConfig.setNotNull( fieldIndex, True )

Set a constraint expression:

formConfig.setExpression( fieldIndex, myExpression )

Not Null constraint in edit form:

enter image description here

answered Jul 26, 2017 at 19:59
0
1

Since the setters for field constraints won't be available until QGIS 3 on 29th September 2017, I couldn't wait that much to get this problem solved, so I worked around it by catching the event of featureAdded from the active layer in the qgis interface:

First I define a function to check the constraints :

def check_constraints(self, fid):
 feature_iterator = self.iface.activeLayer().getFeatures(QgsFeatureRequest(fid))
 feature = next(feature_iterator)
 code = feature.attributes()[0]
 if not code:
 self.iface.messageBar().pushMessage("Error", "the code of the entity is null !t", level=QgsMessageBar.CRITICAL)

and then I bind it the active layer of the QgsInterface

 self.iface.activeLayer().featureAdded.connect(self.check_constraints)

PS: I'm using it inside a class of a plugin that's why I use self.iface and not directly qgis.utils.iface

answered Jul 26, 2017 at 8:42
1
  • Constraints are already available in QGIS 2.18 Commented Sep 8, 2017 at 10:10
0
# Get the layer by its name
topo_details_layer_name = 'Topo_Details'
details_layer = QgsProject.instance().mapLayersByName(
 topo_details_layer_name)[0]
name_field_index = details_layer.fields().indexFromName('Name')
details_layer.setFieldConstraint(
 name_field_index, QgsFieldConstraints.ConstraintNotNull)
answered Mar 19, 2024 at 3:20

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.