Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

[BE] Skip foreign-key existence queries in CompetencyCriterion.save()

Abierto
#898 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
76/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
django, mysql, postgresql, python, sqlite

Línea de trabajo

Start with CompetencyCriterion.save() in src/openedx_learning/applets/cbe/models/criteria.py and check the existing _validate_rule_source() exclusion in api.py. Add or update tests for foreign-key reads during bulk_update_competency_criteria() with override values and a named profile, while confirming override payload validation still runs. Done means each changed criterion adds two queries and missing references are still rejected by the database.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

User Story

As a course author bulk-editing competency criteria, I want the update to skip redundant database reads for each criterion, in order to keep large batches fast.

Description

CompetencyCriterion.save() calls full_clean() with no exclude. As a result, Django runs a separate SELECT on every save to check that each foreign key's row still exists. We need to exclude the foreign keys from that call and let the database's foreign-key constraints enforce them.

Context

Acceptance Criteria

Scenario: Saving a criterion doesn't re-read the rows it points at
  Given an existing criterion
  When its rule is changed and it is saved
  Then the save writes the criterion and its history record
  And it does not read the criterion's group, tag association, or rule profile

Scenario: Bulk update cost no longer includes the foreign-key reads
  Given a batch of criteria in one group whose rule the update changes
  When the bulk update applies override values, and again when it names a rule profile
  Then each changed criterion adds 2 queries to the batch, in both cases

Scenario: Override payload validation still runs on save
  Given a criterion
  When it is saved with override values whose payload doesn't fit the rule type
  Then the save is refused with a validation error, as before

Scenario: A reference to a missing row is still refused
  Given a criterion that points at a group, tag association, or rule profile that doesn't exist
  When it is saved
  Then the database refuses the write
Technical Details

This is a suggested approach, not the source of truth. The User Story, Description, and Acceptance Criteria define what must be true when the work is done.

Approach

  1. In CompetencyCriterion.save() in src/openedx_learning/applets/cbe/models/criteria.py, pass exclude=["group", "object_tag", "rule_profile"] to full_clean(). _validate_rule_source() in api.py already uses the same exclude. clean() still runs, so override payload validation is unchanged.
  2. Excluding a field also skips its not-null check. A dangling or missing foreign key now fails as an IntegrityError from the database instead of a ValidationError from save(). The API paths look up the group and tag before they build a criterion, so they shouldn't notice. Confirm that no caller catches the ValidationError for this case.
  3. On SQLite and PostgreSQL, Django creates foreign-key constraints as DEFERRABLE INITIALLY DEFERRED, so the database checks a dangling reference at commit, not at save(). A test for the last scenario needs to force the check, for example with connection.check_constraints(). MySQL checks immediately.
  4. Pin the per-criterion cost with a django_assert_num_queries test on bulk_update_competency_criteria(): a fixed number of queries, plus 2 per changed criterion, for both override values and a named profile.

Additional context

Lenguaje dominante
Python
Estrellas
10
Forks
33
Merge medio
2 d 11 h
PR fusionados (30 d)
22

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de openedx/openedx-core

Todos los issues de openedx/openedx-core

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.