2
votes

I am trying to have this function limit a user to only one vote per image. However it currently lets all votes through. If I change "if existing_vote != 0:" to "if existing_vote == 0:" it lets no votes through. Thoughts?

class VoteHandler(webapp.RequestHandler):

def get(self):
    #See if logged in
    self.Session = Session()
    if not 'userkey' in self.Session:
        doRender(
            self,
            'base/index.html',
            {'error' : 'Please login to vote'})
        return

    #If user hasn't voted - if user doesn't have a vote on that image object
    key = self.request.get('photo_id')
    vurl = models.Image.get_by_id(int(key))

    #pull current site vote total & add 1

    existing_vote = models.Vote.all().filter('user=', self.Session['userkey']).filter('photo=',vurl).count()

    if existing_vote != 0:
        self.redirect('/', { })
    else:    
        newvote = models.Vote(user=self.Session['userkey'], url=vurl)
        vurl.votes += 1
        vurl.put()
        logging.info('Adding a vote')

        #Create a new Vote object
        newvote = models.Vote(user=self.Session['userkey'], url=vurl)
        newvote.put()    
        self.redirect('/', { })

For the Models:

class User(db.Model):

account = db.StringProperty()

password = db.StringProperty()

name = db.StringProperty()

created = db.DateTimeProperty(auto_now=True)

class Image(db.Model):

user = db.ReferenceProperty(User)

photo_key = db.BlobProperty()

website = db.StringProperty()

text = db.StringProperty()

created = db.DateTimeProperty(auto_now=True)

votes = db.IntegerProperty(default=1)

class Vote(db.Model):

user = db.ReferenceProperty(User) #See if voted on this site yet

photo = db.ReferenceProperty(Image) #To apply vote to right URL

upvote = db.IntegerProperty(default=1)

created = db.DateTimeProperty(auto_now=True)

2
What does the count equal? Add a logging statement and try to figure out what this is actually returning: existing_vote = models.Vote.all().filter('user=', self.Session['userkey']).filter('photo=',vurl).count() A better implementation would be to create a vote class as a child object of the User in an entity group with the photoId as a key. Off topic, but do you mind me asking why you implemented your own User class instead of using Google Accounts or OpenID?Ikai Lan
1. Logs show existing_vote = 0 2. n00b here, and was going off tutorial in a book that created a User class...Emile

2 Answers

1
votes

Looks like your filter on user is wiping out every existing vote, i.e., the equality there is never satisfied. And indeed I'm not sure how I'd satistfy an equality check on a reference propertly. Why not change

user = db.ReferenceProperty(User) #See if voted on this site yet

to, e.g.,

useraccount = db.StringProperty()  # account of user who cast this vote

Then the comparison becomes a simple equality check between strings and is sure to work without any complication -- simplicity is generally preferable, when feasible.

1
votes

On this line here:

existing_vote = models.Vote.all().filter('user=', self.Session['userkey']).filter('photo=',vurl).count()

You need to put a space between the 'photo' and the '=' in the filters - otherwise, it's attempting to filter for a property called 'photo='. This should work:

existing_vote = models.Vote.all().filter('user =', self.Session['userkey']).filter('photo =',vurl).count()