ohjuny
ohjuny

Reputation: 481

Django Template: How to refer to individual objects in for loop in Javascript?

I am building an online puzzle app using Django which contains a solution feature. Each solution has a up_vote and down_vote field, each of which are ManyToManyFields with the User model. I take the .count() of each field and subtract them to calculate the net votes.

I am trying to create a feature so that when the user clicks the "up" button, the up_vote field of the solution is updated. I am thinking of using Ajax for this. In order to do this, I need to be able to reference the specific solution in Javascript. Here is my current template:

{% for solution in solutions %}
            <div class="card bg-light">
                <div class="card-header subtitle">
                        <div class="triple-left">{{ solution.datetime }} by <a href="{% url 'profile' username=solution.user.username %}">{{ solution.user.username }}</a></div>
                        {% if user == solution.user or user.profile.teacher %}
                        <div class="triple-right">
                            <a href="{% url 'edit_solution' puzzleID=solution.puzzle.id solutionID=solution.id %}">edit</a>
                            &nbsp;&nbsp;
                            <a class="delete" href="{% url 'delete_solution' puzzleID=solution.puzzle.id solutionID=solution.id %}">delete</a>
                        </div>
                        {% endif %}
                        <div class="triple-center">
                            <a class="up-not-clicked" id="up_vote">&uArr;</a>
                            &nbsp;&nbsp;
                            {{ solution.points }}
                            &nbsp;&nbsp;
                            <a id="down_vote">&dArr;</a>
                        </div>
                </div>
                <a href="{% url 'solution' puzzleID=solution.puzzle.id solutionID=solution.id %}">
                <div class="card-body">
                    <h5 class="card-title">{{ solution.title }}</h5>
                    <p class="card-text">{{ solution.content|linebreaks }}</p>
                </div>
                </a>
            </div>
        <br>
    {% endfor %}

Note this line:

<a class="up-not-clicked" id="up_vote">&uArr;</a>

In my Javascript, I have an event listener for when this is clicked. Here is my Javascript:

$(document).ready(function(){
    $('#up_vote').on('click', function () {
        console.log(!!I need some way of referring to the solution that was clicked!!)
    });
});

In my Javascript, how do I refer to the specific solution object that was up voted?

Thank you

Edit: Added models as requested by wtreston

My models:

class Solution(models.Model):
user = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
)
puzzle = models.ForeignKey(
    Puzzle,
    on_delete=models.CASCADE,
)
title = models.CharField(max_length=30)
content = models.TextField()
up_votes = models.ManyToManyField(User, related_name='up_votes', blank=True)
down_votes = models.ManyToManyField(User, related_name='down_votes', blank=True)
datetime = models.DateTimeField(default=timezone.now, blank=True)

@property
def points(self):
    return self.up_votes.count() - self.down_votes.count() + 1

def __str__(self):
    return self.title

class Comment(models.Model):
user = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
)
solution = models.ForeignKey(
    Solution,
    on_delete=models.CASCADE,
)
title = models.CharField(max_length=30)
content = models.TextField()
datetime = models.DateTimeField(default=timezone.now, blank=True)

def __str__(self):
    return self.title

Upvotes: 0

Views: 148

Answers (1)

wtreston
wtreston

Reputation: 1061

So firstly its better practice to create a new table called 'Ratings' for example, which stores the user who rated it, the puzzle they're rating and wether it is an upvote or downvote.

Next for your JavaScript problem: IDs are meant to be unique, so you're better off using a class as an identifier in this case. In order to get the puzzles ID, I would set the items ID to the puzzle ID using jinja, like below:

<a class="up-not-clicked" id="{{ puzzle.ID }}">&uArr;</a>

Now for the javascript:

$(document).ready(function(){
    $('.up-not-clicked').each(function(){
        $(this).on('click', function(){
            var puzzleID = $(this).id;
            //Your code here
        })
    })
});

Now you have the puzzle ID, you can use it to find which puzzle the user has clicked on

Upvotes: 1

Related Questions