Domanda

Ho un report Web che utilizza un modulo Django (nuovi moduli) per i campi che controllano la query utilizzata per generare il report (data di inizio, data di fine, ...).Il problema che sto riscontrando è che la pagina dovrebbe funzionare utilizzando i valori iniziali del modulo (non associati), ma non riesco ad accedere al campo clean_data a meno che non chiamo is_valid().Ma is_valid() fallisce sempre sui moduli non associati.

Sembra che i moduli di Django siano stati progettati con il caso d'uso della modifica dei dati in modo tale che un modulo non associato non sia realmente utile per qualcosa di diverso dalla visualizzazione di HTML.

Ad esempio, se ho:

if request.method == 'GET':
    form = MyForm()
else:
    form = MyForm(request.method.POST)

if form.is_valid():
    do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

is_valid() fallirà se questo è un GET (poiché non è associato) e se lo faccio:

if request.method == 'GET':
    form = MyForm()
    do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])
else:
    form = MyForm(request.method.POST)
    if form.is_valid():
       do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

la prima chiamata a do_query attiva eccezioni su form.cleaned_data, che non è un campo valido perché is_valid() non è stato chiamato.Sembra che devo fare qualcosa del tipo:

if request.method == 'GET':
    form = MyForm()
    do_query(form['start_date'].field.initial, form['end_date'].field.initial)
else:
    form = MyForm(request.method.POST)
    if form.is_valid():
       do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

ovvero non esiste un'interfaccia comune per recuperare i valori del modulo tra un modulo associato e uno non associato.

Qualcuno vede un modo più pulito per farlo?

È stato utile?

Soluzione

Se aggiungi questo metodo alla classe del modulo:

def get_cleaned_or_initial(self, fieldname):
        if hasattr(self, 'cleaned_data'):
            return self.cleaned_data.get(fieldname)
        else:
            return self[fieldname].field.initial

potresti quindi riscrivere il tuo codice come:

if request.method == 'GET':
    form = MyForm()
else:
    form = MyForm(request.method.POST)
    form.is_valid()

do_query(form.get_cleaned_or_initial('start_date'), form.get_cleaned_or_initial('end_date'))

Altri suggerimenti

Non vincolato significa che non ci sono dati associati al modulo (né iniziali né forniti successivamente), quindi la convalida potrebbe non riuscire.Come menzionato in altre risposte (e nella tua conclusione), devi fornire valori iniziali e verificare sia i dati associati che i valori iniziali.

Il caso d'uso dei moduli è l'elaborazione dei moduli E convalida, quindi è necessario disporre di alcuni dati da convalidare prima di accedere cleaned_data.

Puoi passare un dizionario di valori iniziali al tuo modulo:

if request.method == "GET":
    # calculate my_start_date and my_end_date here...
    form = MyForm( { 'start_date': my_start_date, 'end_date': my_end_date} )
...

Vedi il documentazione API dei moduli ufficiali, dove lo dimostrano.

modificare:In base alle risposte di altri utenti, forse questa è la soluzione più pulita:

if request.method == "GET":
    form = MyForm()
    form['start_date'] = form['start_date'].field.initial
    form['end_date'] = form['end_date'].field.initial
else:
    form = MyForm(request.method.POST)
if form.is_valid():
    do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

Non l'ho provato però;qualcuno può confermare che funziona?Penso che sia meglio che creare un nuovo metodo, perché questo approccio non richiede altro codice (possibilmente non scritto da te) per conoscere il tuo nuovo accesso "magico".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top