0

I've set up a .gpkg file with 10 fields, some of which I want to be entered by user and some to be generated automatically when creating a polygon (multipart) feature.

For example I've set up a "CREATED BY" field which is supposed to record the user name of the person who has created the feature. In the layer properties > Attributes form I have specified the "CREATED BY" field to be editable, not NULL, enforce not NULL constraint, default value = @user_full_name (which in preview correctly returns my name) and it's supposed to apply default value on update.

When I create a polygon in QGIS all of the default values get populated correctly. (There's some other ones like fid, date and time, polygon x centre, polygon y center and polygon centre). All work fine.

Now what I'm having problems with is that I'm creating a plugin which downloads data from a REST API call, loads the data into a vector layer and creates a polygon from a buffer (around points from the API call). Here only the fid value gets populated automatically and "CREATED BY", "DATE AND TIME" etc are left a empty / null. From what I know when using .setAttributes in python a "None" value should return the default value specified in the attributes form, but for some reason this doesn't happen.

# Begin editing the output layer
new_buffer_layer.startEditing()
# Select all features
new_buffer_layer.selectAll()
# Copy selected features
new_buffer_layer.dataProvider().addFeatures(new_buffer_layer.selectedFeatures())
# End editing the output layer
new_buffer_layer.commitChanges()

# Begin editing the "SLM SITES - MULTIPART" layer
slm_sites_layer = QgsProject.instance().mapLayersByName("SLM SITES - MULTIPART")[0]
slm_sites_layer.startEditing()
    
# Clear any existing features in the layer
# slm_sites_layer.dataProvider().deleteFeatures(slm_sites_layer.allFeatureIds())

# Paste features without attributes
for feature in new_buffer_layer.getFeatures():
    new_feature = QgsFeature()
    new_feature.setGeometry(feature.geometry())
    # Set attributes
    new_feature.setAttributes([
        None, # FEATURE ID - Doesn't work
        "F2 - SITE NAME", # SITE NAME - Works
        "F3 - CLIENT", # CLIENT - Works
        None, # CREATED BY - Doesn't work
        "F5 - CREATED FOR", # CREATED FOR - Works
        None, # DATE AND TIME - Doesn't work
        None, # POLYGON X CENTRE - Doesn't work
        None, # POLYGON Y CENTRE - Doesn't work
        None, # POLYGON CENTRE COORDINATES
        "737737" # JOB NUMBER - Works
    ])  # Adjust values as needed
slm_sites_layer.dataProvider().addFeature(new_feature)
    
# End editing the "SLM SITES - MULTIPART" layer
slm_sites_layer.commitChanges()

TABLE ATTRIBUTE FORMS

2
  • That shouldn't matter. I'm not transferring the data from fields of the source layer to the target layer. In essence I'm taking the geometries only from the source layer and then manually assigning attributes to the objects in the target layer via code.
    – LiMoNiZeR
    Apr 4 at 21:57
  • So I did some more digging around and turns out QDateTime.currentDateTime in python returns the same value as now() in QGIS as a defulat value (for example in my case both work and return 05/04/2024 09:32:22 (GMT Summer Time)).
    – LiMoNiZeR
    Apr 5 at 8:46

1 Answer 1

1

So it turns out (looking at it now it makes perfect sense) that the default code in QGIS is different than the code in python. I just needed to find the correct code for returning the values FOR PYTHON not QGIS. Below is the edited code that returns the values as needed:

# Paste features without attributes
for feature in new_buffer_layer.getFeatures():
    new_feature = QgsFeature()
    new_feature.setGeometry(feature.geometry())
    # Set attributes
    new_feature.setAttributes([
        None, # FEATURE ID - Works
        "F2 - SITE NAME", # SITE NAME - Works
        "F3 - CLIENT", # CLIENT - Works
        os.getlogin(), # CREATED BY - Works
        "F5 - CREATED FOR", # CREATED FOR - Works
        QDateTime.currentDateTime(), # DATE AND TIME - Works
        new_feature.geometry().centroid().asPoint().x(), # POLYGON X CENTRE - Works
        new_feature.geometry().centroid().asPoint().y(), # POLYGON Y CENTRE - Works
        "{},{}".format(new_feature.geometry().centroid().asPoint().x(),new_feature.geometry().centroid().asPoint().y()), # Works
        "737737" # JOB NUMBER - Works
        ])  

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.