Как установить исходные данные для модели администратора Django add instance?

Как я могу установить начальное значение поля в автоматически сгенерированной форме для добавления экземпляра модели 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, я получаю приятную форму с пустыми полями для названия и описания. Я бы хотел, чтобы поле описания задавалось шаблоном, который я получаю, вызывая функцию.

Моя самая лучшая попытка получить там:

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?

Ответ 1

Вам нужно включить self в качестве первого аргумента в определении метода __init__, но не следует включать его при вызове метода суперкласса.

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)

Ответ 2

Подход Alasdair хорош, но устарел. Подход Radev выглядит неплохо, и, как упоминалось в комментарии, мне кажется, что в документации нет ничего.

Кроме того, поскольку Django 1.7 имеет функцию get_changeform_initial_data в ModelAdmin, которая устанавливает начальные значения формы:

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

Ответ 3

Более 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

Приветствия;