Home > Software engineering >  Why can't I display my data filtered to active user?
Why can't I display my data filtered to active user?

Time:09-19

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})
  • Related