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.
3 Answers 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:
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
-
Constraints are already available in QGIS 2.18Matthias Kuhn– Matthias Kuhn2017年09月08日 10:10:58 +00:00Commented Sep 8, 2017 at 10:10
# 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)