Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

211
Visualizações
Check if user has voted on a certain poll

I've got a list of polls (questions), and would like to check if a certain User has voted on that certain poll. Here's my models:

class Question(models.Model):
    has_answered = models.ManyToManyField(User)
    question_text = models.CharField(max_length=80)

    def __str__(self):
        return self.question_text

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=100)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

Here's my view when a user votes on a poll:

def poll_answer(request):
    if request.method == 'POST':
        answer = request.POST.get('answer')
        question = request.POST.get('question')

        q = Question.objects.get(question_text=question)

        choice = Choice.objects.get(id=answer)
        choice.votes += 1
        choice.save()
        ...

I've added a ManyToMany field in my Question model, which after reading the docs I believe is the right way to link the list of Users who have voted on a certain Question, but i'm not sure to be honest. The end goal is to put in my template something like: if request.user in question.has_answered: don't display the poll

How exactly would I go about this?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

There are many ways to do that, I would prefer to create another model for a vote:

class Vote(models.Model):
    user = models.ForeignKey(User, unique=True)

class Choice(models.Model):
    question = models.ForeignKey(Question, related_name='choices')
    choice_text = models.CharField(max_length=100)
    votes = models.ForgeinKey(Vote)

With that models you can count the number of votes easily: And you have the benefit of know what exactly user voted for in the question

Choice.objects.get(pk=PK).votes.count()

To detect if a user already voted:

if Vote.objects.filter(question=1, user=user_id).count() == 1
user_id voted for question 1 already
over 4 years ago · Santiago Trujillo Relatório

0

You can create a vote view like this:

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except:
        return render(request, 'your_question_page.html', {'question': question,
            'error_message': "Please select an option"})
    else:
        selected_choice.votes += 1
        selected_choice.save()

        return redirect('polls:result_page_view', question_id=question_id)

The above vote view will extract the option id of the chosen option but if there is an error like no option chosen then except block will execute and print the given error message otherwise it increases the vote count of the selected option by 1 and save it. Hope this helps you.

over 4 years ago · Santiago Trujillo Relatório

0

First off, there are some logical and schematic issues that need to be addressed.

You are filtering questions based on a non-unique field question_text that is likely to return more than one object. You should either retrieve the question by id:

q = Question.objects.get(pk=question)

or make question_text field unique:

question_text = models.CharField(max_length=80, unique=True)

Second, incrementing votes by one via Python may lead to race conditions that might occur when two users want to increment votes at the same time. This is why there exists F objects in Django which lets you do the increment in database level:

from django.db.models import F

def poll_answer(request):
    ...
    choice = Choice.objects.get(id=answer)
    choice.votes = F("votes") + 1
    choice.save()
    ...

I've got a list of polls (questions), and would like to check if a certain User has voted on that certain poll.

By your design, you can't because you are not storing who voted which question. You are just incrementing votes field when a user votes on a question.

One way to do that, you can change votes field to ManyToManyField and start storing users who have put a vote on a choice:

class Question(models.Model):
    text = models.CharField(max_length=80, unique=True)

    def __str__(self):
        return self.text

class Choice(models.Model):
    question = models.ForeignKey(Question)
    choice = models.CharField(max_length=100)
    votes = models.ManyToMany(User)

so you can check if a user has voted on a poll as follows:

has_voted = request.user.choice_set.filter(question=question).exists()

Furthermore, it seems to me that voting action here can act like an intermediate model between Question and User models so you might want to take a look at how to define extra fields on many-to-many relationships section in Django docs.

If I were in your shoes, I would do something like below:

class Question(models.Model):
    text = models.CharField(max_length=80, unique=True)
    voters = models.ManyToManyField(User, through="Vote")

class Choice(models.Model):
    question = models.ForeignKey(Question)
    text = models.CharField(max_length=100)

class Vote(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    choice = models.ForeignKey(Choice, on_delete=models.CASCADE)
    voted_at = models.DateTimeField(auto_now_add=True)
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda