简体   繁体   中英

Return the result of a method in a QuerySet.values() or values_list()?

When calling .values() or .values_list() on a QuerySet you can pass in the specific fields you want returned, or even fields you want from related tables. What I'm wanting to do is include the result of a method defined on the model, in addition to some fields, for example:

class MyModel(models.Model):

    name = models.CharField()

    def favouriteNumber(self):
        return random.randint(1,10)

list(MyModel.objects.all().values('name','favouriteNumber'))
=> [{'name':'Bob', 'favouriteNumber':6}, {'name':'Fred', 'favouriteNumber':4}]

The above doesn't work, but is what I'm wanting to do, in the same way that the templating language can treat model methods without parameters just like fields.

The reason I'm wanting to do this is so that I can pass the information to the JavaScript in the front end to use instead of making calls back to the server to retrieve it each time.

Assuming the above (or something similar) isn't possible, I know I could loop over my values() result afterwards and add in the extra information manually.. what would be the most efficient (and clean) way to do that?

You might want to try using only() instead of values() . Like values() it will only fetch the specified fields from the database, but unlike values() it will return actual instance objects that you can call methods on.

That way, whether you're looping in the view or the template, you can access the method in addition to the specified fields.

If you need dictionary-like structures (for json.dumps() , say) you can just construct them in a comprehension:

instances = MyModel.objects.only('name')
data = [{'name': instance.name, 
         'favourite': instance.favouriteNumber()} for instance in instances]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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