0

我是 Django 的新手,对 Python 也有一些了解。我正在尝试找到循环查询集并在每个模型上设置变量的惯用方式。基本上我的模型依赖于来自 api 的值,并且模型方法必须将它的一个属性乘以这个 api 值才能获得最新的正确值。

目前我正在视图中执行此操作并且它有效,但我不确定这是实现我想要的正确方法。我必须在别处复制这个循环。

有没有办法可以将循环逻辑封装到查询集方法中,以便可以在多个地方使用?

注意:我在每个模型实例上设置的变量只是一个常规属性,没有保存到 db。我只需要能够设置该变量,而不是保存它。

我有这个 atm(我正在使用 django-rest-framework):

class FooViewSet(viewsets.ModelViewSet):
    model = Foo
    serializer_class = FooSerializer

    bar = # some call to an api

    def get_queryset(self):
        # Dynamically set the bar variable on each instance!
        foos = Foo.objects.filter(baz__pk=1).order_by('date')
        for item in foos:
            item.needs_bar = self.bar

        return items

我认为这样的事情会更好:

def get_queryset(self):
    bar = # some call to an api
    # Dynamically set the bar variable on each instance!
    return Foo.objects.filter(baz__pk=1).order_by('date').set_bar(bar)

我认为 api 命中应该在控制器中,然后注入到模型的实例中,但我不确定你是如何做到这一点的。我一直在寻找查询集和管理器,但仍然无法弄清楚,也无法确定它是否是实现我想要的最佳方法。

谁能建议用 django 建模的正确方法?

谢谢。

4

1 回答 1

0

您可以在查询集项目上设置一些新属性,但它们不会更新数据库(将仅保存在本地命名空间中)。我想您想重新计算模型的字段,将其乘以某个值:

class Foo(models.Model):
     calculated_field = models.BigIntegerField(default=0)

def save(self, *args, **kwargs):
    if self.pk is not None:  # it's not a new record
       foo = kwargs.get('foo')
       if foo:
           self.calculated_field = self.calculated_field * int(foo)
    super(Foo, self).save(*args, **kwargs) # Call the "real" save() method.


 def get_queryset(self):
        bar = # some call to an api
        # Dynamically set the bar variable on each instance!
        foos = Foo.objects.filter(baz__pk=1).order_by('date')
        for item in foos:
            item.save(foo=bar)
       # return updated data
       return Foo.objects.filter(baz__pk=1).order_by('date')

如果您将同时运行此代码,有时您可能需要使用事务。

于 2013-11-01T15:50:48.313 回答