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

Pieter
4,4721 gold badge11 silver badges26 bronze badges
asked Apr 4, 2024 at 16:44
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. Commented Apr 4, 2024 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)). Commented Apr 5, 2024 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
 ]) 
answered Apr 5, 2024 at 11:41

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.