On Thu, Oct 7, 2010 at 4:54 AM, meenakshi <meenak...@mbi.ucla.edu> wrote:
> Hi,
>   I am new to Django and Python and have been working through the
> tutorial.  I would like to modify the polls app in the tutorial such
> that I can track individual users who vote in a poll, keep a record of
> their choice, and not allow any user to vote more than once in any
> given poll.
>   Briefly, there are many polls, each poll being linked to several
> choices.  Each user can vote in many polls, but is allowed to vote
> only once in each individual poll.  Whats the best way to enforce
> this?
> I tried to enforce this by using the unique_together feature to bind a
> specific user, poll, choice combination together (within the Choice
> class). It didnt work.  Here is the code I tried:
>
> from django.db import models
> import datetime
>
> class User(models.Model):
>    name = models.CharField(max_length=100)
>    email = models.EmailField()
>    def __unicode__(self):
>        return self.name
>
> class Poll(models.Model):
>    question = models.CharField(max_length=200)
>    pub_date = models.DateTimeField('date published')
>    def __unicode__(self):
>        return self.question
>
> class Choice(models.Model):
>    poll = models.ForeignKey(Poll)
>    user = models.ManyToManyField(User)
>    choice = models.CharField(max_length=200)
>    votes = models.IntegerField()
>
>    def __unicode__(self):
>        return self.choice
>
>    class Meta:
>        unique_together = ("poll", "user", "choice")
>
>
> My error message:
> Error: One or more models did not validate:
> polls.choice: "unique_together" refers to user. ManyToManyFields are
> not supported in unique_together.
> polls.choice: "unique_together" refers to user. This is not in the
> same model as the unique_together statement.
>
> I would appreciate any suggestions/corrections,
>
> Thanks,
> Meenakshi
>

Make your model heirarchy such that adding a vote is modelled by the
creation of a single row in a single table, and the creation of that
row is constrained by the DB to respect your conditions (1 vote per
user per poll):

class User(models.Model):
  pass

class Poll(models.Model):
  pass

class Choice(models.Model):
  poll = models.ForeignKey(Poll)

class UserPollChoice(models.Model):
  poll = models.ForeignKey(Poll)
  user = models.ForeignKey(User)
  choice = models.ForeignKey(Choice)

  class Meta:
    unique_together = ( 'poll', 'user', )

You will have to use aggregates to get the scores of the poll out with
this scenario though. Something like this would work:
  from django.db.models import Count
  poll.choice_set.annotate(num_votes=Count('userpollchoice'))

Cheers

Tom

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to