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

时间:2022-05-26 15:52:47

How can I set an initial value of a field in the automatically generated form for adding a Django model instance, before the form is displayed? I am using Django 1.3.1.

在显示表单之前,如何在自动生成的表单中设置字段的初始值以添加Django模型实例?我正在使用Django 1.3.1。

My model is the following:

我的模型如下:

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

and the current admin form is really nothing special

而目前的管理形式真的没什么特别的

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

When I use the admin page to add a new instance of Foo, I get a nice form with empty fields for title and description. What I would like is that the description field is set with a template that I obtain by calling a function.

当我使用管理页面添加一个新的Foo实例时,我得到一个很好的表单,其中包含标题和描述的空字段。我想要的是描述字段是通过调用函数获得的模板设置的。

My current best attempt at getting there is this:

我目前最好的尝试是:

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

but if I try this I get this Django error:

但如果我尝试这个我得到这个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

I don't know what is wrong here, and what I should do to make it work. What I also find strange about this error (apart from the fact that I see it at all) is that there is no FooForm in my code at all?

我不知道这里有什么问题,我应该做些什么才能让它发挥作用。我也觉得奇怪的是这个错误(除了我完全看到它的事实)是我的代码中根本没有FooForm?

3 个解决方案

#1


18  

You need to include self as the first argument in your __init__ method definition, but should not include it when you call the superclass' method.

您需要将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)

Having said that, a model field can take a callable for its default, so you may not have to define a custom admin form at all.

话虽如此,模型字段可以将其默认值设置为可调用,因此您可能根本不必定义自定义管理表单。

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

#2


17  

Alasdair's approach is nice but outdated. Radev's approach looks quite nice and as mentioned in the comment, it strikes me that there is nothing about this in the documentation.

Alasdair的方法很好但过时了。 Radev的方法看起来很不错,正如评论中所提到的那样,令我印象深刻的是文档中没有任何相关内容。

Apart from those, since Django 1.7 there is a function get_changeform_initial_data in ModelAdmin that sets initial form values:

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

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

#3


8  

More then 3 years later, But actually what you should do is override admin.ModelAdmin formfield_for_dbfield .. like this:

超过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

Cheers;

干杯;

#1


18  

You need to include self as the first argument in your __init__ method definition, but should not include it when you call the superclass' method.

您需要将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)

Having said that, a model field can take a callable for its default, so you may not have to define a custom admin form at all.

话虽如此,模型字段可以将其默认值设置为可调用,因此您可能根本不必定义自定义管理表单。

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

#2


17  

Alasdair's approach is nice but outdated. Radev's approach looks quite nice and as mentioned in the comment, it strikes me that there is nothing about this in the documentation.

Alasdair的方法很好但过时了。 Radev的方法看起来很不错,正如评论中所提到的那样,令我印象深刻的是文档中没有任何相关内容。

Apart from those, since Django 1.7 there is a function get_changeform_initial_data in ModelAdmin that sets initial form values:

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

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

#3


8  

More then 3 years later, But actually what you should do is override admin.ModelAdmin formfield_for_dbfield .. like this:

超过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

Cheers;

干杯;