i am trying to write a logic that would display each user’s rating in list view not detail view. The Problem now is it displays the same rating for all the creator. When i try doing this in detail view it is quite easy becuase i have to firstly get the creator of the user like this
def CourseDetailView(request, course_slug):
course = Course.objects.get(slug=course_slug)
profile = Profile.objects.get(user=course.course_creator)
creator_average = CreatorRating.objects.filter(profile=profile).aggregate(Avg('rating'))['rating__avg']
now when i pass in `creator_average` in the course detail page, it gets the exact rating for the user that created the course.
To achive the same result now in ListView seems difficult because instead of returning each user specific rating it just return the same rating for all the creators.
models.py
class CreatorRating(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True, related_name="profile_rating")
rating = models.DecimalField(max_digits=2, decimal_places=1, choices=CREATOR_RATING)
review = models.TextField()
date = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
def __str__(self):
return f"{self.profile.full_name} - {self.rating}"
class Meta:
verbose_name = "Creator Rating"
class Creator(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True)
my_experience = models.TextField()
date = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
I’m listing out all the creators from the creator model, now I want to display the rating of a each creator under thier name.
It appears that you may have multiple redundant ForeignKey references.
Creator has FKs to both User and Profile.
CreatorRating has FKs to both User and Profile
Profile has an FK to User.
This structure means that Creator could have different CreatorRatings associated with it if there is an inconsistency between those reference sets.
Can a User actually be referenced by multiple Creator objects?
Does the Profile reference in CreatorRating have a different meaning than the reference to User?
Can a User have multiple Profile objects referring to it?
Yes it does have different meaning, the User only stores the users account i.e username and password, while the Profile stores the images, full_name, bio and others.
Ok, so the relationship between Creator and User should be a OneToOneField, not ForeignKey.
I understand the difference between the User and the Profile. What I am referring to is the relationship to each of them from the CreatorRating object.
The problem is you have two references in CreatorRating - one to a User and one to a Profile. Are they referring to two different people or the same person? (If they are to two different people, what’s the meaning of those two relationships. And if they’re supposed to refer to the same person, then you don’t want to have two fields, because they could end up referring to two different people, giving you different problems.)
Again, this should then be a OneToOne relationship, not a ForeignKey
It does in that it removes the ambiguity that existed in the previous structure.
You have four different “paths” between tables (Creator → User → CreatorRating, Creator → Profile → CreatorRating, Creator → User → Profile → CreatorRating, and Creator → Profile → User → CreatorRating). Since those tables are related through ForeignKey relationships (meaning they can return multiple different elements), you could get different results based upon how the query is written.
There was actually no way to ensure you were going to get the “right” answer in your attempt to calculate those averages.
But in the detail view, I get the right answer which is the average_rating for each course creator, now in the list view: I don’t know how to still specifically get the average for each creators that I am listing out in the forloop. You know the details view have no forloop, so it made it a bit easier to get the averge_rating. Is There’s no way to query the filter to get the average_for each user in the list view I mean??
It shows that’s the query set should be limited to one slicing, I know that’s because I’m querying a filter by another filter and not a get. I don’t know how to achieve this??
Hopefully you’d understand what I’m trying to explain.
You are getting the right answer now because your database is still consistent. You probably don’t have any of the errors caused by inconsistent data possible with your previous data structures.
I do know what you’re trying to achieve here, but we needed to resolve those potential data problems first.
In the general sense, what you’re going to want to do is create your query and annotate (not aggregate) the queryset with the value you wish to obtain
In general terms, your query is going to look something like this: