There is a model, for example

t1 = models.IntegerField(...) t2 = ... t3 = ... t1name = models.CharField(...) t2name = ... ... 

t1, t2, t (n) - numbers. I do a sample of the base on 1 object and need to calculate the sum of only these fields (t (n)) Whispers the cap that I do not need to do this:

 a = Quote.objects.filter(user__username=Fool).order_by('-id')[0] itog= a.t1 + a.t2 + a.t3 .... 
  • By the way, the first and last objects can be obtained through the methods first () and last (), respectively. Please do not cut a single object. - FeroxTL

1 answer 1

I will add a little bit to make it clearer. Suppose we have a model

 class MyModel(models.Model): t1 = models.IntegerField(...) t2 = ... t3 = ... t1name = models.CharField(...) t2name = ... 

We get one object obj = MyModel.objects.get(id=1) . Further we will work with such designations.

In django, all the service information about the fields is dumped in MyModel._meta.fields . Accordingly, the task is to filter this list in the search for the fields we need, then get their values ​​and return them as a sum. Dynamically get the field values, as in the whole python, can be obtained through getattr . Well, let's give some example

First try to get t1

 >>> [field for field in MyModel._meta.fields if field.name == 't1'] [<django.db.models.fields.IntegerField: t1>] 

Ok, works. But we need to get all t [n]. Let's write a regular season!

and there will be one more problem

 import re >>> [field for field in MyModel._meta.fields if re.match(r'^t\d+$', field.name)] [<django.db.models.fields.IntegerField: t1>, <django.db.models.fields.IntegerField: t2>, <django.db.models.fields.IntegerField: t3>, <django.db.models.fields.IntegerField: t4>] 

Regular selects all fields that begin with t and then one or more numbers.

What if we don't have IntegerField ? Let's do another check on the field type:

 >>> [field for field in MyModel._meta.fields if re.match(r'^t\d+$', field.name) and field.get_internal_type() == 'IntegerField'] [<django.db.models.fields.IntegerField: t1>, <django.db.models.fields.IntegerField: t2>, <django.db.models.fields.IntegerField: t3>, <django.db.models.fields.IntegerField: t4>] 

Now nobody will deceive us. It remains only to sum up the values ​​from these fields and add it all as a method of the model instance:

 def sum_f_fields(self): field_names = [field for field in MyModel._meta.fields if re.match(r'^t\d+$', field.name) and field.get_internal_type() == 'IntegerField'] values = [getattr(self, field.name, None) or 0 for field in field_names] returm sum(values)