Emile
Emile

Reputation: 3484

VoteHandler in Google App Engine

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)

Upvotes: 2

Views: 191

Answers (2)

Nick Johnson
Nick Johnson

Reputation: 101149

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()

Upvotes: 1

Alex Martelli
Alex Martelli

Reputation: 881735

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.

Upvotes: 1

Related Questions