I am trying to populate field "L_M" with the default value of "Length" or with the result of multiplication between "Length" and 0.3048 if "LengthUnit" = 2, which stands for Feets.

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface
from qgis.PyQt.QtCore import QVariant

# create layer
layer = iface.mapCanvas().currentLayer() 
it = layer.getFeatures(QgsFeatureRequest())


# add field

new_Field1 = "L_M"
idq = layer.fieldNameIndex(new_Field1)

if idq == -1:
    layer.addAttribute(QgsField(new_Field1, QVariant.Double, 'double', 20, 4))

layer.updateFields() # tell the vector layer to fetch changes from the provider

idl = layer.fieldNameIndex('Length')
e = QgsExpression ("idl * 0.3048")

for feat in it:
    if feat['LengthUnit'] == 2:
        layer.changeAttributeValue(feat.id(), layer.fieldNameIndex('L_M'), e.evaluate(feat))
        layer.changeAttributeValue(feat.id(), layer.fieldNameIndex('L_M'), idl)

layer.updateFields() # tell the vector layer to fetch changes from the provider

The result I get is 'L_M' field populated with '10.000' value, and NULL value for entries with 'LengthUnit' = 2.

What is the best approach to get the multiplication between fields in a new field?

P.S. As I see it, my script doesn't even read proper values from the 'Length' field, which I don't know why. It's a Double type field also.

1 Answer 1


The QGSExpression considers the column name, not the column ID. So you would need to change your expression to

e = QgsExpression ('"Length"* 0.3048')

Then in the loop, the else case should set the value of the feature's length, not of the field ID

        layer.changeAttributeValue(feat.id(), layer.fieldNameIndex('L_M'), feat['Length'])
  • Perfect @JGH. Many thanks for pointing that out. Another thing was to make the field name escape: e = QgsExpression ("\"Length\" * 0.3048")
    – kidd
    Jun 4, 2018 at 13:04
  • @kidd ah yes, I have updated the answer
    – JGH
    Jun 4, 2018 at 14:35

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.