[bug] Template.clean() corrections land one write late over the REST API

Aperta
#1,478 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@krrishnaik ci sta già lavorando.

Dal 4/9/2026.

  • #1483 di @mansiverma897993 — chiusa senza merge

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
52/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
django, python
Ambito
api, backend

Direzione di ricerca

Inizia tracciando ValidatedModelSerializer.validate() e il punto di ingresso TemplateSerializer.validate_vpn, quindi esamina Template.clean() e il percorso di salvataggio PUT/PATCH. Riproduci i casi PATCH descritti nell’issue che riguardano solo il tipo e quelli che riguardano solo i campi obbligatori. Il lavoro è completato quando ogni modifica applica le relative correzioni nella stessa scrittura, con test che coprano entrambi i casi e la compatibilità con openwisp-utils#760.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

bug

Describe the bug

ValidatedModelSerializer.validate() only applies incoming data when there is no
instance (creation); on PUT/PATCH it runs full_clean() on the instance as
loaded. So Template.clean() never sees the change being saved, and its
type-scoped corrections are applied one write late — the offending write stores
an inconsistent row, and some later unrelated write happens to fix it.

TemplateSerializer.validate_vpn does not catch this: it only fires when both
type and vpn are present in initial_data, so a type-only PATCH bypasses it.

Steps To Reproduce

  1. Create a template with type="vpn" and a VPN attached.
  2. PATCH /api/v1/controller/template/<pk>/ with
    {"type": "generic", "config": {"interfaces": []}} → 200.
  3. Re-read the row: type is generic but vpn is still set, contradicting
    clean()'s "clears VPN specific fields if type is not VPN".
  4. PATCH anything else, e.g. {"name": "renamed"} → only now is vpn set to
    None.

Same shape for required/default: PATCH {"required": true} stores
required=True, default=False, and default becomes True only on a later
write.

Expected behavior

The type change itself should clear vpn/auto_cert, and required should
force default on the same write.

Depends on openwisp/openwisp-utils#760 — and note that if that
lands as copy-based validation, Template.clean() will need to stop correcting
by assignment, since those corrections would no longer be saved at all.

Screenshots

N/A.

System Informatioon:

  • OS: Pop!_OS 24.04 LTS
  • Python Version: Python 3.13.5
  • Django Version: Django 5.2.16
  • Browser and Browser Version (if applicable): N/A (REST API)

Also: openwisp-controller 1.2.3, openwisp-utils 1.2.2, djangorestframework
3.16.1.

Lingua principale
Python
Stelle
794
Fork
339
Merge medio
9h 56m
PR unite (30g)
32

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di openwisp/openwisp-controller

Tutte le issue di openwisp/openwisp-controller

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.