如何使用字典更新对象的成员?

时间:2022-09-02 13:53:29

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

我正在编写一个Django应用程序,它执行各种功能,包括通过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.

因此,某个内部应用程序向/import/?发送请求。= 1 b = 2和c = 3,例如。在视图中,我想创建一个新的对象foo = foo(),并将foo的成员设置为请求中的数据。得到字典。

Here is what I'm doing now:

我现在正在做的是:

  1. Request sent to /import/?a=1&b=2&c=3
  2. 请求发送到/导入/ ? = 1 b = 2和c = 3
  3. View creates new object: foo = Foo()
  4. 视图创建新对象:foo = foo ()
  5. Object is updated with data.
  6. 对象是用数据更新的。

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.

显然,这很乏味,而且容易出错。URL中的数据与对象的成员具有完全相同的名称,因此它是一个简单的1- 1映射。

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

理想情况下,我想做如下的事情:

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

or something to that effect.

或者类似的东西。

Thanks!

谢谢!

4 个解决方案

#1


19  

You can use the setattr function to dynamically set attributes:

可以使用setattr函数动态设置属性:

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

#2


3  

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

如果请求。GET是一个字典,而Foo类不使用__slots__,那么这个也可以:

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

#3


1  

You've almost got it.

你几乎都得到了。

foo = Foo(**request.GET)

should do the trick.

应该足够了。

#4


1  

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.

如果您正在使用它创建一个模型对象,然后持久化,我强烈推荐使用一个ModelForm。在Django的规范方法中,这将按照您所描述的方式进行,并添加验证。

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".

然后,假设它被绑定到/导入/,一个到达/导入/?a=Test&b=1将插入一个新的Foo,其中a= "Test", b="1"。

#1


19  

You can use the setattr function to dynamically set attributes:

可以使用setattr函数动态设置属性:

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

#2


3  

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

如果请求。GET是一个字典,而Foo类不使用__slots__,那么这个也可以:

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

#3


1  

You've almost got it.

你几乎都得到了。

foo = Foo(**request.GET)

should do the trick.

应该足够了。

#4


1  

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.

如果您正在使用它创建一个模型对象,然后持久化,我强烈推荐使用一个ModelForm。在Django的规范方法中,这将按照您所描述的方式进行,并添加验证。

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".

然后,假设它被绑定到/导入/,一个到达/导入/?a=Test&b=1将插入一个新的Foo,其中a= "Test", b="1"。