2012-04-03 18 views
11

¿Cómo puedo establecer un valor inicial de un campo en el formulario generado automáticamente para agregar una instancia de modelo de Django, antes de que se muestre el formulario? Estoy usando Django 1.3.1.¿Cómo establecer los datos iniciales para el modelo de administrador de Django Agregar formulario de instancia?

Mi modelo es el siguiente:

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

y la forma de administración actual es realmente nada especial

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

Cuando uso la página de administración para añadir una nueva instancia de Foo, consigo un buen formulario con campos vacíos para el título y la descripción. Lo que me gustaría es que el campo de descripción esté configurado con una plantilla que obtengo llamando a una función.

Mi actual mejor intento de llegar allí es la siguiente:

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 

pero si intento esto me sale este error de 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 

No sé lo que está mal aquí, y que debería hacer para que funcione Lo que también me parece extraño acerca de este error (aparte del hecho de que lo veo en absoluto) es que no hay ningún FooForm en mi código.

Respuesta

17

Debe incluir self como primer argumento en su definición de método __init__, pero no debe incluirlo cuando llame al método de la superclase.

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) 

Dicho esto, un campo modelo puede tomar un exigible por su default, por lo que no puede tener que definir un formulario de administración personalizada en absoluto.

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

Vaya, que funcionó como un encanto! Un mensaje increíblemente críptico, por cierto, por un error tan tonto ... ¡Muchas gracias por su ayuda! –

+0

Por cierto, también intenté con éxito su segunda sugerencia, que es incluso más limpia, ¡gracias de nuevo! –

+0

Encontré que establecer kwargs ['initial'] causaba un error al guardar el formulario. Me había propuesto una cláusula if: si 'inicial' en kwargs.keys():.. kwargs [ 'inicial'] actualización (... Esto funcionó para la visualización de los valores iniciales y actualizarlos – Sven

7

más de 3 años más tarde, Pero en realidad lo que debe hacer es anular admin.ModelAdmin formfield_for_dbfield .. así:

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 

Saludos;

+0

Muy bonito. Es extraño, pero no hay nada en la documentación: https: // docs. djangoproject.com/en/1.8/ref/contrib/admin/ – Wtower

+0

Desafortunadamente, el administrador de Django está "mal" documentado. –

15

El enfoque de Alasdair es bueno pero desactualizado. El enfoque de Radev se ve bastante bien y como se menciona en el comentario, me parece que no hay nada sobre esto en la documentación.

Aparte de estos, ya que Django 1.7 existe una función get_changeform_initial_data en ModelAdmin que establece los valores iniciales del formulario:

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

por alguna razón en 1.10.2 este método no se llama en absoluto, aunque está presente en los documentos – scythargon

+0

@scythargon Acabo de probarlo en 1.10.2 y para mí funcionó según lo documentado. – Wtower

+0

Es fácil perder la pista de todos los ganchos disponibles para ModelAdmin. ¡Gracias por esto! –

Cuestiones relacionadas