Search code examples
pythondjangovoting

How can I make sure a user votes just once in python django?


I have a Entry model which has a "Pushes" field and I want each user to "push" (vote) once. I searched and couldn't find what I needed.

Here is my model:

class Entry(models.Model):
    title = models.CharField(max_length = 100)
    link = models.URLField(verify_exists=False)
    posted = models.DateTimeField(auto_now_add=True)
    submitter = models.ForeignKey(User, blank=True, null=True)
    pushes = models.PositiveIntegerField(default=0)

    def __unicode__(self):
        return self.title + " - " + unicode(self.submitter)

And here is my Homepage view:

def homepage(request):
    entries = Entry.objects.all().order_by('-posted')
    paginator = Paginator(entries, 30)

    try: page = int(request.GET.get('page', '1'))
    except ValueError: page = 1

    try:
        entries = paginator.page(page)
    except (InvalidPage, EmptyPage):
        entries = paginator.page(paginator.num_pages)

    return render_to_response('index.html', {'entries' : entries},
                              context_instance=RequestContext(request))

How can I make it so that a user can't push more than once?
Do i have to create a new function?
Should I change something in the models?


Solution

  • If you want to only allow unique voters, you can't just track votes with a number - you need to do one of two things:

    • Record votes as independent objects that are tied to a user
    • Record a user's voting history as part of that user's object

    The first is almost always simpler to do, especially if your users are going to be voting in more than one "election".

    Typically what you would do is create a vote object that is tied to both the thing being voted for and the user doing the voting, and then create a unique key on both of those items so that only one instance of any given pairing is allowed to exist.