2013-09-18 12 views
1

Что у меня в models.py:Позвольте пользователю голосовать только один раз. Джанго

class Poll(models.Model): 
    question = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 
    is_active = models.BooleanField(default=True) 
    # The rest of code... 

class Choice(models.Model): 
    poll = models.ForeignKey(Poll) 
    choice_text = models.CharField(max_length=200) 
    votes = models.IntegerField(default=0) 
    # The rest of code... 

class Voter(models.Model): 
    user = models.ForeignKey(User) 
    poll = models.ForeignKey(Poll) 

Что у меня в vote зрения в views.py:

@login_required 
def vote(request, poll_id): 
    # Some code... 
    # And here is the checking happens. 
    voters = [user.id for user in Voter.objects.filter(poll__id=poll_id)] 
    if request.user.id in voters: 
     return render(request, 'polls/detail.html', { 
     'poll': p, 
     'error_message': "Sorry, but you have already voted." 
     }) 
    try: 
     selected_choice = p.choice_set.get(pk=request.POST['choice']) 
    except (KeyError, Choice.DoesNotExist): 
     # Redisplay the poll voting form. 
     return render(request, 'polls/detail.html', { 
     'poll': p, 
     'error_message': "You didn't select a choice." 
     }) 
    else: 
     selected_choice.votes +=1 
     selected_choice.save() 
     v = Voter(user=request.user, poll=p) 
     v.save() 
     return HttpResponseRedirect(reverse('polls:results', args=(p.id,))) 

Но этот код работает немного странно.

Я создал 5 опросов для целей тестирования. И этот код работает только для один из них. Только в одном из этих опросов я получаю сообщение об ошибке, когда я пытаюсь проголосовать дважды. В остальном этом опросе, код дает возможность проголосовать столько раз, сколько захотите.

И я понятия не имею, почему. У тебя есть идеи?

+0

Вы можете просто сделать это сами, добавив 'import pdb; pdb.set_trace() 'после _ # И вот проверка происходит ._. Затем посмотрите на значения «избирателей», возможно, они не те, которые вы ожидали. – MrKsn

+1

FYI: вы можете сделать это: 'Voter.objects.filter (poll_id = poll_id, user_id = request.user.id) .exists()', чтобы проверить, проголосовал ли пользователь. Что касается вопроса, можете ли вы отправить тестовый код, который дает неожиданный результат? – mariodev

ответ

6

Voter Иды не обязательно будут соответствовать вашим User ids. Это объясняет, почему вы иногда видите, что оно работает (когда идентификатор и идентификатор пользователя случайно совпадают). Заменить:

voters = [user.id for user in Voter.objects.filter(poll__id=poll_id)] 
if request.user.id in voters: 

с

if Voter.objects.filter(poll_id=poll_id, user_id=request.user.id).exists() 

Это лучшая практика, чтобы бэкенд база данных сделать проверку для вас.

Смежные вопросы