tags:

views:

331

answers:

4

I'm writing a Django app that performs various functions, including inserting, or updating new records into the database via the URL.

So some internal application sends off a request to /import/?a=1&b=2&c=3, for example. In the view, I want to create a new object, foo = Foo() and have the members of foo set to the data in the request.GET dictionary.

Here is what I'm doing now:

  1. Request sent to /import/?a=1&b=2&c=3
  2. View creates new object: foo = Foo()
  3. Object is updated with data.

Here is what I got thus far:

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

Obviously this is tedious and error prone. The data in the URL has the exact same name as the object's members so it is a simple 1-to-1 mapping.

Ideally, I would like to do able to do something like this:

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

or something to that effect.

Thanks!

+7  A: 

You can use the setattr function to dynamically set attributes:

for key,value in request.GET.items():
    setattr(foo, key, value)
Ants Aasma
Thanks. I must have had a brain fart because I looked over the documentation built-in functions.
Nick Presta
You may want to swap `a_dict` with `request` and `obj` with `foo` to match Nick's code.
Colin Burnett
I updated it if that is fine with Ants. Thanks again!
Nick Presta
+1  A: 

You've almost got it.

foo = Foo(**request.GET)

should do the trick.

Daniel Roseman
I get the error: __init__() keywords must be strings
Nick Presta
+1  A: 

If you are using this to create a model object that then gets persisted, I'd strongly recommend using a ModelForm. This would do what you described, in the canonical way for Django, with the addition of validation.

To expand -- I didn't mean to use it for form output, just form input. As follows:

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

Then, assuming it's bound to /import/, a GET to /import/?a=Test&b=1 would insert a new Foo with a = "Test" and b="1".

Matthew Christensen
I don't want a form or any user interaction. The script that sends the data is run on a cron job overnight to update the database that Django uses for other things.
Nick Presta
+2  A: 

If request.GET is a dictionary and class Foo does not use __slots__, then this should also work:

# foo is a Foo instance
foo.__dict__.update(request.GET)
ΤΖΩΤΖΙΟΥ