Melissa Malala
Melissa Malala

Reputation: 89

Project object has no attribute "review_set"

I'm getting an error that says Project object has no attribute review_set when trying to get the mean of ratings using Numpy.

The HTML looks something like this, what could be the problem?

<h5>{{ project.review.count }} reviews ({{ 
project.average_design | floatformat }} average rating of design)</h5>
<h5>{{ project.review.count }} reviews ({{ 
project.average_content | floatformat }} average rating of content)</h5>
<h5>{{ project.review.count }} reviews ({{ project.average_usability | floatformat }} average rating of usability)</h5>

models:

class Project(models.Model):
    title = models.TextField(max_length=200, null=True, blank=True, default="title")
    project_image = models.ImageField(upload_to='picture/', null=True, blank=True)
    description = models.TextField()
    project_url=models.URLField(max_length=250)
    def average_design(self):
        design_ratings = list(map(lambda x: x.design_rating, self.review_set.all()))
        return np.mean(design_ratings)

    def average_usability(self):
        usability_ratings = list(map(lambda x: x.usability_rating, self.review_set.all()))
        return np.mean(usability_ratings)

    def average_content(self):
        content_ratings = list(map(lambda x: x.content_rating, self.review_set.all()))
        return np.mean(content_ratings)



class Review(models.Model):
    RATING_CHOICES = (
        (1, '1'),
        (2, '2'),
        (3, '3'),
        (4, '4'),
        (5, '5'),
        (6, '6'),
        (7, '7'),
        (8, '8'),
        (9, '9'),
        (10, '10'),

    )
    project = models.ForeignKey(Project, null=True, blank=True, on_delete=models.CASCADE, related_name="review")
    user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE, related_name='user')
    image = models.ForeignKey(Image, on_delete=models.CASCADE, related_name="project", null=True, blank=True)
    comment = models.TextField()
    design_rating = models.IntegerField(choices=RATING_CHOICES, null=True, blank=True)
    usability_rating = models.IntegerField(choices=RATING_CHOICES, null=True, blank=True)
    content_rating = models.IntegerField(choices=RATING_CHOICES, null=True, blank=True)

Upvotes: 0

Views: 748

Answers (2)

Melissa Malala
Melissa Malala

Reputation: 89

Thanks, it has worked. I edited the related_name to "reviews" and made the migrations on the database.

Upvotes: 0

Alasdair
Alasdair

Reputation: 309049

You have related_name="review".

project = models.ForeignKey(Project, null=True, blank=True, on_delete=models.CASCADE, related_name="review")

Therefore you should use self.review.all() instead of self.review_set.all().

It would be clearer if you used related_name="reviews" (since each project can have multiple reviews).

project = models.ForeignKey(Project, null=True, blank=True, on_delete=models.CASCADE, related_name="reviews")

and then you would use self.reviews.all().

Note that using related_name="user" and related_name="project" for your other foreign keys doesn't make sense. These are used to get the related reviews for a given user and image respectively, so it would be better to use related_name="reviews" for both of them.

Upvotes: 3

Related Questions