2009-06-02 26 views
11

Estoy escribiendo una aplicación de Django que realiza varias funciones, incluida la inserción o la actualización de nuevos registros en la base de datos a través de la URL.¿Cómo actualizo los miembros de un objeto usando un dict?

Por lo que algunas aplicaciones internas envían una solicitud al /import/?a=1&b=2&c=3, por ejemplo. En la vista, quiero crear un nuevo objeto, foo = Foo() y tener los miembros de foo establecidos en los datos en el diccionario request.GET.

Esto es lo que estoy haciendo ahora:

  1. solicitud enviada a /import/?a=1&b=2&c=3
  2. Vista crea nuevo objeto: foo = Foo()
  3. objeto se actualiza con los datos.

Aquí es lo que tengo hasta ahora:

foo.a = request['a'] 
foo.b = request['b'] 
foo.c = request['c'] 

Obviamente, esto es tedioso y propenso a errores. Los datos en la URL tienen exactamente el mismo nombre que los miembros del objeto, por lo que es una asignación simple de 1 a 1.

Idealmente, me gustaría hacer capaz de hacer algo como esto:

foo = Foo() 
foo.update(request.GET) 

o algo por el estilo.

Gracias!

+1

La solución presentada por las hormigas hace lo que quiere, pero ¿cómo está manejando la validación y el tipo de conversión? O no son motivo de preocupación (encuentro esto difícil de creer). –

+0

No importan. Esto se está utilizando completamente en casa, donde los datos se insertan en una base de datos (con validación) y luego (aquí) se insertan en otra. –

Respuesta

19

Puede utilizar la función setattr para ajustar dinámicamente atributos:

for key,value in request.GET.items(): 
    setattr(foo, key, value) 
+0

Gracias. Debo haber tenido un problema en el cerebro porque revisé las funciones integradas de documentación. –

+0

Es posible que desee cambiar 'a_dict' por' request' y 'obj' con' foo' para que coincida con el código de Nick. –

+0

Lo actualicé si eso está bien con las hormigas. ¡Gracias de nuevo! –

1

te han casi lo consiguió.

foo = Foo(**request.GET) 

deberían hacer el truco.

+0

Recibo el error: __init __() las palabras clave deben ser cadenas –

+1

Las palabras clave pueden aparecer como unicode y causar ese error. algo que buscar ... Este código funcionó para mí con tres formas diferentes de escribir __init __() – JCotton

+2

Eso no resuelve el caso de uso de actualizar un modelo existente con un dict de valores nuevos. –

1

Si está utilizando esto para crear un objeto modelo que luego persista, le recomiendo usar un ModelForm. Esto haría lo que describiste, de forma canónica para Django, con la adición de validación.

Expandir: no pretendía usarlo para la salida del formulario, solo formé la entrada. En la siguiente manera:

class Foo(models.Model): 
     a = models.CharField(max_length=255), 
     b = models.PositiveIntegerField() 

class FooForm(forms.ModelForm): 
     class Meta: 
      model = Foo 

def insert_foo(request): 
     form = FooForm(request.GET) 
     if not form.is_valid(): 
      # Handle error conditions here 
      pass 
     else: 
      form.save() 

     return HttpResponse('Your response') 

Entonces, asumiendo que es obligado a/importación /, un GET a/importación/a = Prueba & b = 1 insertaría un nuevo Foo con a = "Test" y b = "1? ".

+0

No quiero un formulario ni ninguna interacción del usuario. La secuencia de comandos que envía los datos se ejecuta en un trabajo de cron durante la noche para actualizar la base de datos que Django utiliza para otras cosas. –

3

Si request.GET es un diccionario y class Foo no utiliza __slots__, entonces esto también debería funcionar:

# foo is a Foo instance 
foo.__dict__.update(request.GET) 
+0

Ya no funciona en Django 1.3+ –

+0

Esto funciona en Django 1.6 con un verdadero objeto dict. No intenté solicitar. OBTENER o .POST. – James

Cuestiones relacionadas