Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to count row from backref in template?

I have a question. I need to count MemePositiveRating for Meme in template.
I try meme.memeratingpositive|length but not working.
There is any idea to do it with Abstract layer in models ? Here are my scripts:

home.html:

<a class="mr-2" href="#">{{ meme.memeratingpositive|length }}</a>

models.py:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

class Meme(models.Model):
    title = models.CharField(max_length=100)
    meme = models.ImageField(upload_to='memes')
    creation_date = models.DateField(default=timezone.now)
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)

    def __str__(self):
        return f'Meme id: {self.id}'

class MemeRating(models.Model):
    meme = models.ForeignKey(Meme, on_delete=models.CASCADE, related_name = 'ratings', blank = True, null = True)
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)

    class Meta:
        abstract: True

class MemeRatingPositive(MemeRating):
    pass
    
class MemeRatingNegative(MemeRating):
    pass

views.py:

class HomeView(ListView):
    template_name = 'meme/home.html'
    model = Meme
    context_object_name = 'memes'
    
    def get_queryset(self):
        return Meme.objects.filter(memestatus__is_in_moderating_room=False, memestatus__is_in_waiting_room=False)

>Solution :

Instead of the current model structure, I would suggest like this:

class Meme(models.Model):
    title = models.CharField(max_length=100)
    meme = models.ImageField(upload_to='memes')
    creation_date = models.DateField(default=timezone.now)
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)

    def __str__(self):
        return f'Meme id: {self.id}'

class MemeRating(models.Model):
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)

    class Meta:
        abstract: True

class MemeRatingPositive(MemeRating):
    meme = models.ForeignKey(Meme, on_delete=models.CASCADE, related_name = 'memeratingpositive', blank = True, null = True)
    
class MemeRatingNegative(MemeRating):
    meme = models.ForeignKey(Meme, on_delete=models.CASCADE, related_name = 'memeratingnegative', blank = True, null = True)

Then you can call in the template like this:

{{ meme.memeratingpositive.count }}

Here I changed the related name for both of the Negative and Positive Memes model class.

Apart from that, I think the meme rating model should not have multiple tables, instead ratings can be stored in same MemeRating model, and use Enum to determine its positive or negative. In that way, you would not have to change too much when you want different expression other than positive or negative. Here is how I would suggest:

class Meme(models.Model):
    title = models.CharField(max_length=100)
    meme = models.ImageField(upload_to='memes')
    creation_date = models.DateField(default=timezone.now)
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)

    def __str__(self):
        return f'Meme id: {self.id}'

    @property
    def positive_ratings_count(self):
        self.rating.filter(expression_type="POS").count()

    @property
    def negative_ratings_count(self):
        self.rating.filter(expression_type="NEG").count()

class MemeRating(models.Model):
    CHOICES= [
        ("POS", "Positive"),
        ("NEG", "Negative"),
    ]
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
    meme = models.ForeignKey(Meme, on_delete=models.CASCADE, related_name = 'rating', blank = True, null = True)
    expression_type = models.CharField(max_length=3, choices=CHOICES, default="POS")

Then use it in template:

{{ meme.positive_rating_count }}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading