如何为Django管理模型添加实例表单设置初始数据?

如何为Django管理模型添加实例表单设置初始数据?,django,forms,model,admin,Django,Forms,Model,Admin,在显示表单之前,如何在自动生成的表单中设置字段的初始值以添加Django模型实例?我正在使用Django 1.3.1 我的模型如下: class Foo(models.Model): title = models.CharField(max_length=50) description = models.TextField() 而当前的管理表单也没什么特别的 class FooAdmin(admin.ModelAdmin): ordering = ('title',) 当我使用管

在显示表单之前,如何在自动生成的表单中设置字段的初始值以添加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?

您需要将
self
作为
\u init\u
方法定义中的第一个参数,但在调用超类方法时不应该包含它

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)
话虽如此,一个模型字段可以为其调用一个callable,所以您可能根本不需要定义一个定制的管理表单

class Foo(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField(default=get_default_content)
三年多后, 但实际上,您应该做的是为_dbfield覆盖admin.ModelAdmin formfield。。像这样:

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

干杯

阿拉斯代尔的方法不错,但已经过时了。Radev的方法看起来相当不错,正如评论中所提到的,我觉得文档中没有这方面的内容

除此之外,由于Django 1.7,ModelAdmin中有一个函数用于设置初始表单值:

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

哇,真是妙极了!对于这样一个愚蠢的错误,顺便说一句,令人敬畏的神秘信息。。。非常感谢你的帮助!顺便说一句,我也成功地尝试了你的第二个建议,它更干净,再次感谢!我发现在保存表单时设置kwargs['initial']会导致错误。我在kwargs.keys()中设置了一个if子句:if'initial':kwargs['initial'].update(…这用于显示初始值并更新它们。@Sven很好。我已经更新了我的答案,将
initial
设置为空的dict,如果它不在
kwargs
中。非常好。这很奇怪,但文档中没有这样的东西:Django管理员是“方式”不幸的是,您可以删除
字段=super…
行,设置
kwargs['initial']='My initial description'
(类似于
'counter'
字段),然后是保存一行的
return super…
。由于某种原因,在1.10.2中根本不调用此方法,尽管在docs@scythargon我刚刚在1.10.2中对它进行了测试,对我来说,它是文档化的。很容易忘记ModelAdmin的所有可用钩子。谢谢你!面对同样的方法问题,不是吗被调用后,我深入到源代码中。答案很简单,只为新创建的对象调用。更改现有对象不会调用它。是否有类似的函数用于内联线?