I'm trying to display only data for the logged in user in my table. I can display everything using objects.all() but when I filter to the active user, it doesn't work. I have tried changing my context to refer to the queryset as a whole but I get an error saying that I can't perform get on a tuple.
If I have the context as is, I get an error saying 'QuerySet object has no attribute 'user'
Models.py:
class HealthStats(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateField(auto_now=True)
weight = models.DecimalField(max_digits=5, decimal_places=2)
run_distance = models.IntegerField(default=5)
run_time = models.TimeField()
class Meta:
db_table = 'health_stats'
ordering = ['-date']
def __str__(self):
return f"{self.user} | {self.date}"
Views.py:
def health_history(request):
queryset = HealthStats.objects.filter(user=request.user).values()
print(queryset)
print(type(queryset))
context = {
"user": queryset.user_id,
"weight": queryset.weight,
"date": queryset.date,
"run_distance": queryset.run_distance,
"run_time": queryset.run_time,
}
return (request, 'health_hub_history.html', context)
health_hub_history.html:
{% extends 'base.html' %}
{% load static %}
{% block content %}
<div >
<div >
<div >
<h1>My Health History</h1>
</div>
</div>
</div>
<div >
<div >
<div >
<table >
<tr>
<td>User:</td>
<td>Weight (lbs):</td>
<td>Date:</td>
<td>Run Distance (km):</td>
<td>Run Time (HH:MM:SS):</td>
</tr>
{% for stat in queryset %}
<tr>
<td>{{ stat.user }}</td>
<td>{{ stat.weight }} </td>
<td>{{ stat.date }}</td>
<td>{{ stat.run_distance }}</td>
<td>{{ stat.run_time }}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
</div>
{% endblock content %}
Ignore the print statements- just trying to figure out the issue, and will remove them once solved. Also aware that the .values() at the end of the queryset declaration is probably wrong- it's there for the same reasons.
I have been going around in circles for a few hours so any help would be appreciated!
CodePudding user response:
HealthStats.objects.filter(user=request.user).values()
The above code gives you a QuerySet object, not your HealthStats
object. Since User
is a ForeignKey
of HealthStats
, this means that each User
object can have any number of HealthStats
objects associated to it (it can have 0, 1, 2, or more stats). This means the function health_history
should be giving your front end a list of HealthStats
objects.
def health_history(request):
serialized_stats = []
# `filter` also returns a `QuerySet` object which is already iterable.
for stats in HealthStats.objects.filter(user=request.user):
serialized_stats.append({
"user": stats.user_id,
"weight": stats.weight,
"date": stats.date,
"run_distance": stats.run_distance,
"run_time": stats.run_time,
})
context = {
"stats": serialized_stats
}
return (request, 'health_hub_history.html', context)
You'd probably also need to change your html logic to properly handle this.
CodePudding user response:
It's because of your return statement. Try this:
return (request, 'health_hub_history.html', {'queryset': queryset})