Opened 2 hours ago
Last modified 91 minutes ago
#36911 new Bug
bulk_update() incorrectly allows updating GeneratedField (silent failure on SQLite)
| Reported by: | jaffar Khan | Owned by: | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Normal | Keywords: | bulk_update GeneratedField |
| Cc: | jaffar Khan | Triage Stage: | Unreviewed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Currently, bulk_update() does not validate if the fields provided in the fields=[...] argument are GeneratedField instances.
Model:
class Product(models.Model):
price = models.IntegerField()
quantity = models.IntegerField()
total = models.GeneratedField(
expression=models.F("price") * models.F("quantity"),
output_field=models.IntegerField(),
db_persist=True,
)
test function:
def run_test():
# Create product
p = Product.objects.create(price=10, quantity=2)
p.total = 9999
try:
Product.objects.bulk_update([p], fields=["total"])
print("silent failure")
except Exception as e:
print(f"CRASH: {e}")
output:
silent failure
If a developer accidentally includes a GeneratedField in bulk_update(), Django attempts to include it in the SQL UPDATE statement.
On SQLite, this results in a silent failure (no error is raised, but the value is obviously not updated as it is generated).
On strict databases (like PostgreSQL), this likely results in an OperationalError.
Django should raise a FieldError immediately when bulk_update() is called with a GeneratedField, similar to how it handles other read-only fields or invalid field names.
I have a patch and will work on it if this ticket is accepted.