2012-04-03 23 views
11

フォームが表示される前に、Djangoモデルのインスタンスを追加するために自動生成されたフォームのフィールドの初期値を設定するにはどうすればよいですか?私はDjango 1.3.1を使用しています。Django admin model addインスタンスフォームの初期データの設定方法は?

私のモデルは以下の通りです:

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

と現在の管理フォームは私がfooの新しいインスタンスを追加するには、管理ページを使用すると、私が取得本当に

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

特別なものではありませんタイトルと説明のための空のフィールドを持つ素敵なフォーム。私が望むのは、記述フィールドが、関数を呼び出すことによって得られるテンプレートで設定されているということです。

これがあり得ることで私の現在の最高の試み:

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 

が、私はこれをしようとした場合、私は、この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 

私はここで間違っているかわからない、と私はそれを機能させるために何をすべきですか?私はまた、このエラーについて奇妙なことを発見しました(私はそれを全く見ないという事実を除けば)私のコードには全くFooFormがないということですか?

答えて

17

__init__メソッド定義の最初の引数にはselfを含める必要がありますが、スーパークラスのメソッドを呼び出すときは含めるべきではありません。

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) 

あなたがすべてでカスタム管理フォームを定義する必要がないかもしれないので、モデルフィールドは、そのdefaultのための呼び出し可能なを取ることができ、と述べました。

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

うわー、魅力のように働いた:

別にこれらから、Djangoの1.7以降の初期フォームの値を設定しますModelAdminの関数get_changeform_initial_dataがあります!このような愚かな間違いのために途中で恐ろしい秘密のメッセージ...あなたの助けをたくさんありがとう! –

+0

ところで、私はまたあなたの2番目の提案をうまくやってみました。それはさらにクリーナーなので、もう一度感謝します! –

+0

kwargs ['initial']を設定すると、フォームを保存するときにエラーが発生することがわかりました。私は、if節を設定していた: 場合kwargs.keys()の '初期':。。これは、初期値を表示し、それらを更新するために働いていた kwargsから[ '初期']アップデート(... – Sven

7

より後、3年後、 しかし、実際には何をすべきかはadmin.ModelAdmin formfield_for_dbfield ..このような上書きです:

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 

乾杯。

+0

非常にうれしいですが、これは不思議ですが、ドキュメントにそのようなものはありません:https:// docs。 djangoproject.com/en/1。8/ref/contrib/admin/ – Wtower

+0

Djangoの管理者は残念ながら、「方法」の下で文書化されています。 –

15

Alasdairのアプローチは素晴らしいですが、古くなっています。 Radevのアプローチは非常に素晴らしく、コメントに記載されているように、ドキュメントにはこれに関することは何もないと私は思います。

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

何らかの理由で1.10.2でこのメソッドは全く呼び出されていませんが、ドキュメントにはありますが – scythargon

+0

@scythargon 1.10.2でそれをテストしました。 – Wtower

+0

ModelAdminの利用可能なすべてのフックを簡単に追跡できます。ありがとう! –

関連する問題