简体   繁体   English

在查询集上运行的Django模型

[英]Django model operating on a queryset

I'm new to Django and somewhat to Python as well. 我是Django的新手,也是Python的新手。 I'm trying to find the idiomatic way to loop over a queryset and set a variable on each model. 我试图找到惯用的方法来遍历一个查询集并在每个模型上设置一个变量。 Basically my model depends on a value from an api, and a model method must multiply one of it's attribs by this api value to get an up-to-date correct value. 基本上,我的模型依赖于api的值,并且模型方法必须将其属性之一乘以该api值才能获得最新的正确值。

At the moment I am doing it in the view and it works, but I'm not sure it's the correct way to achieve what I want. 目前,我正在视图中进行操作,并且可以正常工作,但是我不确定这是否是实现我想要的正确方法。 I have to replicate this looping elsewhere. 我必须在其他地方复制此循环。

Is there a way I can encapsulate the looping logic into a queryset method so it can be used in multiple places? 有没有一种方法可以将循环逻辑封装到queryset方法中,以便可以在多个地方使用?

NOTE: the variable I am setting on each model instance is just a regular attribute, not saved to db. 注意:我在每个模型实例上设置的变量只是一个常规属性,不会保存到db。 I just need to be able to set that variable, not save it. 我只需要能够设置该变量,而不是保存它。

I have this atm (I am using django-rest-framework): 我有这个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

I would think something like so would be better: 我认为这样会更好:

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)

I'm thinking the api hit should be in the controller and then injected to instances of the model, but I'm not sure how you do this. 我认为api命中应该在控制器中,然后注入到模型实例中,但是我不确定如何做到这一点。 I've been looking around querysets and managers but still can't figure it out nor decided if it's the best method to achieve what I want. 我一直在寻找查询集和管理器,但仍然无法弄清楚,也无法确定这是否是实现我想要的最佳方法。

Can anyone suggest the correct way to model this with django? 有人可以建议使用django建模的正确方法吗?

Thanks. 谢谢。

You can set some new properties on queryset items, but they will not update database (will be saved just in local namespace). 您可以在queryset项目上设置一些新属性,但它们不会更新数据库(仅保存在本地名称空间中)。 I suppose that you want to recalculate field of your model multiplying it by some value: 我想您想重新计算模型的字段并乘以某个值:

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

At some point you might need to use transactions if you will run this code simultaneously. 如果同时运行此代码,则有时可能需要使用事务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM