2012-04-03 10 views
11

Come posso impostare un valore iniziale di un campo nel modulo generato automaticamente per aggiungere un'istanza di modello Django, prima che venga visualizzato il modulo? Sto usando Django 1.3.1.Come impostare i dati iniziali per il modulo di istanza di Django admin model?

Il mio modello è la seguente:

class Foo(models.Model): 
    title = models.CharField(max_length=50) 
    description = models.TextField() 

e la forma di amministrazione corrente è davvero niente di speciale

class FooAdmin(admin.ModelAdmin): 
    ordering = ('title',) 

Quando uso la pagina di amministrazione per aggiungere una nuova istanza di Foo, ho un bel modulo con campi vuoti per titolo e descrizione. Quello che vorrei è che il campo descrizione sia impostato con un modello che ottengo chiamando una funzione.

Il mio attuale miglior tentativo di arrivare è questo:

def get_default_content(): 
    return 'this is a template for a Foo description' 

class FooAdminForm(django.forms.ModelForm): 

    class Meta: 
     model = Foo 

    def __init__(self, *args, **kwargs): 
     kwargs['initial'].update({'description': get_default_content()}) 
     super(FooAdminForm, self).__init__(self, *args, **kwargs) 

class FooAdmin(admin.ModelAdmin): 
    ordering = ('title',) 
    form = FooAdminForm 

ma se provo questo ottengo questo errore Django:

AttributeError at /admin/bar/foo/add/ 
    'FooForm' object has no attribute 'get' 
Request Method: GET 
Request URL: http://localhost:8000/admin/bar/foo/add/ 
Django Version: 1.3.1 
Exception Type: AttributeError 
Exception Value: 'FooForm' object has no attribute 'get' 
Exception Location: /www/django-site/venv/lib/python2.6/site-packages/django/forms/widgets.py in value_from_datadict, line 178 

Non so cosa c'è di sbagliato qui, e cosa dovrei fare per farlo funzionare. Quello che trovo strano anche a questo errore (a parte il fatto che lo vedo) è che non c'è affatto FooForm nel mio codice?

risposta

17

È necessario includere self come primo argomento nella definizione del metodo __init__, ma non includerlo quando si chiama il metodo della superclasse.

def __init__(self, *args, **kwargs): 
    # We can't assume that kwargs['initial'] exists! 
    if not kwargs.get('initial'): 
     kwargs['initial'] = {} 
    kwargs['initial'].update({'description': get_default_content()}) 
    super(FooAdminForm, self).__init__(*args, **kwargs) 

Detto questo, un campo modello può prendere un callable per la sua default, quindi non si può avere definire una forma di amministrazione personalizzato a tutti.

class Foo(models.Model): 
    title = models.CharField(max_length=50) 
    description = models.TextField(default=get_default_content) 
+0

Wow, che ha lavorato come un fascino! Messaggio incredibilmente criptico a proposito di un errore così stupido ... Grazie mille per il vostro aiuto! –

+0

A proposito, ho anche provato con successo il tuo secondo suggerimento, che è ancora più pulito, quindi grazie ancora! –

+0

Ho trovato che l'impostazione di kwargs ['initial'] ha causato un errore durante il salvataggio del modulo. Avevo impostare una clausola if: se 'iniziale' in kwargs.keys():.. kwargs aggiornamento [ 'iniziale'] (... Questo ha funzionato per la visualizzazione dei valori iniziali e li aggiorna – Sven

7

Più di 3 anni più tardi, Ma in realtà ciò che si dovrebbe fare è ignorare admin.ModelAdmin formfield_for_dbfield .. come questo:

class FooAdmin(admin.ModelAdmin): 
    def formfield_for_dbfield(self, db_field, **kwargs): 
     field = super(FooAdmin, self).formfield_for_dbfield(db_field, **kwargs) 
     if db_field.name == 'description': 
      field.initial = 'My initial description' 
     elif db_field.name == 'counter': 
      field.initial = get_counter() + 1 
     return field 

acclamazioni;

+0

Molto bello, è strano ma non c'è nulla di simile nella documentazione: https: // docs. djangoproject.com/en/1.8/ref/contrib/admin/ – Wtower

+0

L'admin di Django è "modo" poco documentato, sfortunatamente. –

15

L'approccio di Alasdair è bello ma obsoleto. L'approccio di Radev sembra molto carino e come accennato nel commento, mi sembra che non ci sia nulla a riguardo nella documentazione.

Oltre a quelli, poiché Django 1.7 esiste una funzione get_changeform_initial_data in ModelAdmin che imposta i valori iniziali di modulo:

def get_changeform_initial_data(self, request): 
    return {'name': 'custom_initial_value'} 
+0

per qualche ragione in 1.10.2 questo metodo non è chiamato affatto, sebbene sia presente nei documenti – scythargon

+0

@scythargon l'ho appena testato in 1.10.2 e per me ha funzionato come documentato. – Wtower

+0

È facile perdere traccia di tutti gli hook disponibili per ModelAdmin. Grazie per questo! –