我有一个GAE应用程序用于投票,每个选民通过电子邮件发送一个唯一的密钥,然后使用该密钥在网页上投票。我想确保每个选民只能投一票,而且投票仍然是匿名的。
我有一个Voter
类,其中包含属性has_voted
和一个Vote
类,其中包含投票属性。我希望投票是匿名的,所以我不希望一个人成为另一个人的父母。
我尝试使用交易更新两者,例如,
def put_vote_transaction(vkey, vote):
voter = Voter.get(vkey)
if voter.has_voted:
return False
else:
voter.has_voted = True
db.put([voter, vote])
return True
但这不起作用,因为选民和投票在不同的实体组中。
我怎样才能确保每个选民只能投一票但保持一票不通?
答案 0 :(得分:1)
正如您所观察到的那样,由于voter
和vote
位于不同的实体组中,因此您无法在同一事务中更新它们。不过,您可以在交易中更新voter
(就像您现在一样),并将vote
记录在与此交易相关联的transactional task中。
答案 1 :(得分:1)
您可以在为他们创建投票项目时将投票项目分配给选民,以便稍后“投入”他们的投票。并且您可以使用单个属性链接投票 - >选民和投票 - > thingToVoteOn(多态)来解决交易问题。我试着说明一下:
如果您的投票模型如下:
Vote(db.Model):
assigned_to = db.ReferenceProperty(collection_name='votes')
假设您投票的项目还有其他模型,例如:
ThingToVoteOn(db.Model):
pass
如果您第一次创建选民时为其分配投票
Voter(db.Model):
# your voter properties
voter = Voter()
voter.put()
vote_to_spend = Vote()
vote_to_spend.assigned_to = voter()
vote_to_spend.put()
之后,选民可以通过将其重新分配给他们投票的实体来“花费”这次投票:
vote = voter.vote
vote.assigned_to = thing_you_vote_on
vote.put()
一旦投票被“投票”,它将不再被分配给选民(因此完全是匿名的),并且它总是发生在同一个交易中,因为它只是一个单一的实体(Vote
)在投票时存储。