2009-06-02 6 views
11

J'écris une application Django qui remplit diverses fonctions, y compris l'insertion ou la mise à jour de nouveaux enregistrements dans la base de données via l'URL.Comment mettre à jour les membres d'un objet à l'aide d'un dict?

Ainsi, certaines applications internes envoient une demande à /import/?a=1&b=2&c=3, par exemple. Dans la vue, je souhaite créer un nouvel objet, foo = Foo(), et définir les membres de foo sur les données du dictionnaire request.GET.

Voici ce que je fais maintenant:

  1. Demande envoyée à /import/?a=1&b=2&c=3
  2. Voir crée nouvel objet: foo = Foo()
  3. objet est mis à jour avec les données.

Voici ce que je suis arrivé jusqu'ici:

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

Évidemment, cela est fastidieux et source d'erreurs. Les données de l'URL ont exactement le même nom que les membres de l'objet. Il s'agit donc d'un mappage 1-à-1 simple.

Idéalement, je voudrais faire en mesure de faire quelque chose comme ceci:

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

ou quelque chose à cet effet.

Merci!

+1

La solution présentée par les fourmis fait ce que vous voulez, mais comment gérez la validation et la conversion type que vous? Ou ne sont pas d'inquiétude (je trouve cela difficile à croire). –

+0

Ils ne sont pas concernés. Ceci est utilisé entièrement en interne, où les données sont insérées dans une base de données (avec validation) puis (ici) insérées dans une autre. –

Répondre

19

Vous pouvez utiliser la fonction setattr pour définir dynamiquement les attributs:

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

Merci. Je dois avoir eu un pet de cerveau parce que j'ai regardé sur les fonctions intégrées de documentation. –

+0

Vous pouvez changer 'a_dict' avec' request' et 'obj' avec' foo' pour faire correspondre le code de Nick. –

+0

Je l'ai mis à jour si ça va avec les fourmis. Merci encore! –

1

Vous ai presque l'ai eu.

foo = Foo(**request.GET) 

devrait faire l'affaire.

+0

Je reçois l'erreur: __init __() Les mots-clés doivent être des chaînes –

+1

Les mots-clés peuvent provenir d'unicode provoquant cette erreur. quelque chose à chercher ... Ce code a travaillé pour moi avec trois façons différentes d'écrire __init __() – JCotton

+2

Cela ne résout pas le cas d'utilisation de la mise à jour d'un modèle existant avec un dict de nouvelles valeurs. –

1

Si vous utilisez ceci pour créer un objet modèle qui est ensuite conservé, je vous recommande fortement d'utiliser un ModelForm. Cela ferait ce que vous avez décrit, de la manière canonique pour Django, avec l'ajout de la validation.

Pour développer - je ne voulais pas l'utiliser pour la sortie de formulaire, juste une entrée de formulaire. Comme suit:

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') 

Ensuite, en supposant qu'il est lié à/import /, un GET/import/a = Test & b = 1 insérerait une nouvelle Foo avec = "Test" et b = "1? ".

+0

Je ne veux pas d'interaction de formulaire ou d'utilisateur. Le script qui envoie les données est exécuté sur un travail cron pendant la nuit pour mettre à jour la base de données que Django utilise pour d'autres choses. –

3

Si request.GET est un dictionnaire et class Foo ne pas utiliser __slots__, cela devrait aussi fonctionner:

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

Ne fonctionne plus dans Django 1.3+ –

+0

Cela fonctionne dans Django 1.6 avec un vrai objet dict. Je n'ai pas essayé request.GET ou .POST. – James

Questions connexes