2010-08-26 16 views
18

Come è possibile ottenere un valore predefinito per un campo da oggetti esistenti di un modello?Django: valore predefinito del campo dalle istanze del modello stesso

ho provato questi e non ci ha funzionato:

1)

class ModelA(models.Model): 
    fieldA = models.CharField(default=self.get_previous()) 

    def get_previous(self): 
     return ModelA.objects.all()[0].fieldA 

NameError: name 'self' is not defined

2)

class ModelA(models.Model): 
    fieldA = models.CharField(default=ModelA.get_previous()) 

    @staticmethod 
    def get_previous(): 
     return ModelA.objects.all()[0].fieldA 

NameError: name 'ModelA' is not defined

3)

class ModelA(models.Model): 
    fieldA = models.CharField(default=get_previous()) 

def get_previous(): 
    return ModelA.objects.all()[0].fieldA 

NameError: global name 'get_previous' is not defined

4)

def get_previous(): 
    return ModelA.objects.all()[0].fieldA 

class ModelA(models.Model): 
    fieldA = models.CharField(default=get_previous()) 

NameError: global name 'ModelA' is not defined

mi è chiaro perché 3) e 4) non funzionerà. Posso immaginare perché 1) non funzionerà - sembra che le proprietà di classe non possano riferirsi all'istanza (cioè a se stesso). Posso immaginare perché 2) non funzionerà - apparentemente non c'è riferimento a ModelA finché l'interprete non passerà per l'intera classe.

Quindi, come devo affrontare questo?

risposta

16

Negli esempi, è necessario rimuovere l'operatore di chiamata ().

Attualmente l'istruzione viene eseguita immediatamente al primo ciclo di analisi di lettura. Specificando il nome del simbolo, invece, la classe Django riceve un puntatore a funzione che verrà eseguito quando ha effettivamente bisogno del valore predefinito.

L'esempio diventa:

def get_previous(): 
    return ModelA.objects.all()[0].fieldA 

class ModelA(models.Model): 
    fieldA = models.CharField(default=get_previous) 

Se avete intenzione di fare questo per un sacco di settori, gli overridding la funzione save, in modo da avere solo per andare a prendere l'oggetto precedente dal database solo una volta.

+1

Buon punto! Nel mio caso però ho molti campi per ottenere il valore predefinito, quindi avrei bisogno di una funzione separata per ognuno. (Ma considererò l'uso di lambda per generalizzare questo, qualcosa come 'lambda: get_default ('field_name')') – grucha

+1

Equivalentemente, dovresti essere in grado di fare 'default = lambda: ModelA.objects.all() [0]. fieldA'. –

+1

Si noti che l'uso di una funzione lambda per impostazione predefinita farà confusione con le migrazioni poiché le funzioni lambda non possono essere serializzate. – Ironbeard

3

Se si desidera solo valore di default di uscita, l'override __getattr__() metodo come questo:

class ModelA(models.Model): 
    # your fields 
    def __getattr__(self, name): 
    if(name == 'fieldA' and !self.fieldA): 
     return self.get_previous() 
    else: 
     return super(ModelA, self).__getattr__(name) 

Salvare il valore di default da oggetto sarà poco difficultier. Prima soluzione che mi viene in mente, override save() method (credo che ci sia una soluzione più semplice)

3

Opzione 1: Use model forms. Si tratta di moduli basati su modelli, in cui è possibile popolare facilmente i propri valori con valori di un'istanza specifica. Questa opzione è buona se si desidera che il valore predefinito sia qualcosa da mostrare all'utente nei moduli, ovviamente.

Opzione 2: Override the model's save method e codificare il controllo lì - se campoA è Nessuno, quindi inserire un valore in esso. Questa opzione è migliore se si desidera che il valore predefinito funzioni sul livello dati e non solo come valori predefiniti del modulo (ovvero, anche per le istanze create in altri modi).

+0

Il mio punto è mostrare il valore predefinito all'utente, non salvarlo se non c'è valore, quindi l'opzione_1 della risposta sembra buona. Anche se mi piace la risposta di vdboor di più dato che si tratta di un livello Python e non del tutto specifico del django. Djangonauts, correggimi se sto andando male ,-) – grucha

Problemi correlati