web-dev-qa-db-ja.com

Django管理モデル追加インスタンスフォームの初期データを設定する方法は?

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

私のモデルは次のとおりです:

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

現在の管理フォームは特別なものではありません

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

管理ページを使用してFooの新しいインスタンスを追加すると、タイトルと説明のフィールドが空のNiceフォームが表示されます。説明フィールドに、関数を呼び出して取得したテンプレートが設定されていることを望みます。

そこに着くための私の現在の最善の試みはこれです:

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がまったくないということです。

21

__init__メソッド定義の最初の引数としてselfを含める必要がありますが、スーパークラスのメソッドを呼び出すときにそれを含めないでください。

def __init__(self, *args, **kwargs):
    # We can't assume that kwargs['initial'] exists! 
    if 'initial' not in kwargs:
        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)
21
Alasdair

Alasdairのアプローチはいいですが時代遅れです。 Radevのアプローチは非常に見栄えがよく、コメントで述べたように、ドキュメントにはこれについて何も記載されていません。

これらとは別に、Django 1.7なので、関数 get_changeform_initial_data 初期フォーム値を設定するModelAdmin内:

def get_changeform_initial_data(self, request):
    return {'name': 'custom_initial_value'}
27
Wtower

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

乾杯;

10
Ramez Ashraf