TypeError: float() argument must be a string or a number, not ‘Profile’

Tags: , ,



Problem:

I’m trying to get the latest value from my model called Profile. But I’ve encountered a problem, when I try to save it to a variable as a float value I get this error TypeError: float() argument must be a string or a number, not 'Profile'. I need this so, I can make calculations with the datas.

Models.py file:

class Profile(models.Model):
      weight = models.FloatField()
      height = models.FloatField()
      bmi = models.FloatField(null=True)
      date = models.DateField(auto_now_add=True)
      user = models.ForeignKey(User, default=None, on_delete=models.CASCADE)

      def __str__(self):
          return self.user.username

Views.py file (relevant parts):

    weight = float(Profile.objects.latest('weight'))
    height = float(Profile.objects.latest('height'))
    bmi = (weight/(height**2))

I searched up this error code here, but I didn’t find any, where ppl wanted to convert from obj to float

Answer

The expression:

Profile.objects.latest('weight')

Does not return a float value, it returns the Profile with the highest weight. But not the weight itself.

You can however easily obtain both values by .aggregate(…) [Django-doc]:

from django.db.models import Max

result = Profile.objects.aggregate(
    max_weight=Max('weight'),
    max_height=Max('height')
)

weight = result['max_weight']
height = result['max_height']

bmi = weight / (height * height)

Note that this not per se the person with the largest bmi. It will simply look for the largest weight and height of all Profiles. (Very) likely the data will originate from two different Profiles.

If you want to calculate the BMI of a Profile, you can use:

profile = Profile.objects.get(pk=my_pk)

bmi = profile.weight / (profile.height * profile.height)

You can obtain the Profile with the largest primary key pk:

profile = Profile.objects.latest('pk')

bmi = profile.weight / (profile.height * profile.height)

but that is not per se the latest added object.



Source: stackoverflow