如何检测用户是否再次尝试投票?
How can I detect if a user tries to upvote once again?
我目前正在实施一个投票系统(应用程序中不会使用否决系统)。我设法在我的应用程序中为 Post 模型创建了一个赞成票 属性。 属性 的默认值为 0,如下所示:
models.py
class User(UserMixin, Model):
username = CharField(unique= True)
email = CharField(unique= True)
password = CharField(max_length = 100)
joined_at = DateTimeField(default = datetime.datetime.now)
is_admin = BooleanField(default = False)
confirmed = BooleanField(default = False)
confirmed_on = DateTimeField(null=True)
class Meta:
database = DATABASE
order_by = ('-joined_at',)
def get_posts(self):
return Post.select().where(Post.user == self)
def get_stream(self):
return Post.select().where(
(Post.user == self)
)
@classmethod
def create_user(cls, username, email, password, is_admin= False, confirmed = False, confirmed_on = None):
try:
with DATABASE.transaction():
cls.create(
username = username,
email = email,
password = generate_password_hash(password),
is_admin = is_admin,
confirmed = confirmed,
confirmed_on = confirmed_on)
except IntegrityError:
raise ValueError("User already exists")
class Post(Model):
timestamp = DateTimeField(default=datetime.datetime.now)
user = ForeignKeyField(
rel_model = User,
related_name = 'posts'
)
name = TextField()
content = TextField()
upvotes = IntegerField(default=0)
url = TextField()
category = TextField()
class Meta:
database = DATABASE
order_by = ('-timestamp',)
我设法通过让用户关注 link:
来增加价值
stream.html
<div class="voting_bar">
<a href="/vote/{{post.id}}"><img src="/static/img/upvote.png"></a>
<p>{{post.upvotes}}</p>
</div>
这将激活具有关联路由的功能:
app.py
@app.route('/vote/<int:post_id>')
def upvote(post_id):
posts = models.Post.select().where(models.Post.id == post_id)
if posts.count() == 0:
abort(404)
post = models.Post.select().where(models.Post.id == post_id).get()
query = models.Post.update(upvotes = (post.upvotes+1)).where(models.Post.id == post_id)
query.execute()
return redirect(url_for('index'))
我的问题是,如何检测用户是否已经投票?我不确定我应该怎么做才能做到这一点。我的计划是,如果我确定用户是否试图再次投票,我会做的只是减少他们之前的投票。
也许您可以在点赞该评论的用户的个人资料中存储一个变量,表示他们之前点赞过该评论?
然后检查投票者之前是否投票过,并在保持计数的同时防止计数增加。
编辑
或者您可以创建一个列表来跟踪像这样投票的人:
class Post(Model):
timestamp = DateTimeField(default=datetime.datetime.now)
user = ForeignKeyField(
rel_model = User,
related_name = 'posts'
)
name = TextField()
content = TextField()
upvotes = IntegerField(default=0)
upvoters = []
url = TextField()
category = TextField()
将投票的用户追加到 post.upvoters
,然后在投票前检查列表
您需要在 post 本身维护一个(去重复的)投票用户列表。
我认为这里最好的方法是创建一个名为 Votes 的单独 table,它将有两列。一个将存储 Post 的 ID,另一个将存储用户的 ID。 table 中的每个条目或行都算作一票。如果用户尝试对特定 post 投票,您将首先查询 Votes table 是否存在具有该用户 ID 的行。如果不存在,则添加投票。但是,如果它确实存在,那么您只需删除投票即可。要获得特定 post 的总票数,您将再次查询 Votes table 并计算给定 post 的行数ID。这也将使您的应用程序具有可扩展性,以防万一您想在将来添加反对票功能。
您为 Django 服务器中的每个用户创建一个帐户,并使用 Django 的内置授权模块对他们进行身份验证。
https://docs.djangoproject.com/en/1.8/topics/auth/
[要检查不同的版本,请将 url 中的 1.8 更改为您想要的版本]
使用此功能,您可以确保只有 1 位用户通过使用标志进行投票。投票完成后,标志就设置好了。
基于 Bidhan 的回答,您可以实现如下内容:
class Upvote(Model):
user = ForeignKeyField(User)
post = ForeignKeyField(Post)
class Meta:
indexes = (
(('user', 'post'), True), # Unique index on user+post
)
您可以将方法添加到 post:
def add_vote(self, user):
try:
with DATABASE.atomic():
Vote.create(user=user, post=self)
except IntegrityError:
return False # User already voted
else:
return True # Vote added
def num_votes(self):
return Vote.select().where(Vote.post == self).count()
也只是一个提示,但是您可以使用 atomic
而不是 transaction
,因为前者支持嵌套。
我目前正在实施一个投票系统(应用程序中不会使用否决系统)。我设法在我的应用程序中为 Post 模型创建了一个赞成票 属性。 属性 的默认值为 0,如下所示:
models.py
class User(UserMixin, Model):
username = CharField(unique= True)
email = CharField(unique= True)
password = CharField(max_length = 100)
joined_at = DateTimeField(default = datetime.datetime.now)
is_admin = BooleanField(default = False)
confirmed = BooleanField(default = False)
confirmed_on = DateTimeField(null=True)
class Meta:
database = DATABASE
order_by = ('-joined_at',)
def get_posts(self):
return Post.select().where(Post.user == self)
def get_stream(self):
return Post.select().where(
(Post.user == self)
)
@classmethod
def create_user(cls, username, email, password, is_admin= False, confirmed = False, confirmed_on = None):
try:
with DATABASE.transaction():
cls.create(
username = username,
email = email,
password = generate_password_hash(password),
is_admin = is_admin,
confirmed = confirmed,
confirmed_on = confirmed_on)
except IntegrityError:
raise ValueError("User already exists")
class Post(Model):
timestamp = DateTimeField(default=datetime.datetime.now)
user = ForeignKeyField(
rel_model = User,
related_name = 'posts'
)
name = TextField()
content = TextField()
upvotes = IntegerField(default=0)
url = TextField()
category = TextField()
class Meta:
database = DATABASE
order_by = ('-timestamp',)
我设法通过让用户关注 link:
来增加价值stream.html
<div class="voting_bar">
<a href="/vote/{{post.id}}"><img src="/static/img/upvote.png"></a>
<p>{{post.upvotes}}</p>
</div>
这将激活具有关联路由的功能:
app.py
@app.route('/vote/<int:post_id>')
def upvote(post_id):
posts = models.Post.select().where(models.Post.id == post_id)
if posts.count() == 0:
abort(404)
post = models.Post.select().where(models.Post.id == post_id).get()
query = models.Post.update(upvotes = (post.upvotes+1)).where(models.Post.id == post_id)
query.execute()
return redirect(url_for('index'))
我的问题是,如何检测用户是否已经投票?我不确定我应该怎么做才能做到这一点。我的计划是,如果我确定用户是否试图再次投票,我会做的只是减少他们之前的投票。
也许您可以在点赞该评论的用户的个人资料中存储一个变量,表示他们之前点赞过该评论? 然后检查投票者之前是否投票过,并在保持计数的同时防止计数增加。
编辑 或者您可以创建一个列表来跟踪像这样投票的人:
class Post(Model):
timestamp = DateTimeField(default=datetime.datetime.now)
user = ForeignKeyField(
rel_model = User,
related_name = 'posts'
)
name = TextField()
content = TextField()
upvotes = IntegerField(default=0)
upvoters = []
url = TextField()
category = TextField()
将投票的用户追加到 post.upvoters
,然后在投票前检查列表
您需要在 post 本身维护一个(去重复的)投票用户列表。
我认为这里最好的方法是创建一个名为 Votes 的单独 table,它将有两列。一个将存储 Post 的 ID,另一个将存储用户的 ID。 table 中的每个条目或行都算作一票。如果用户尝试对特定 post 投票,您将首先查询 Votes table 是否存在具有该用户 ID 的行。如果不存在,则添加投票。但是,如果它确实存在,那么您只需删除投票即可。要获得特定 post 的总票数,您将再次查询 Votes table 并计算给定 post 的行数ID。这也将使您的应用程序具有可扩展性,以防万一您想在将来添加反对票功能。
您为 Django 服务器中的每个用户创建一个帐户,并使用 Django 的内置授权模块对他们进行身份验证。
https://docs.djangoproject.com/en/1.8/topics/auth/
[要检查不同的版本,请将 url 中的 1.8 更改为您想要的版本]
使用此功能,您可以确保只有 1 位用户通过使用标志进行投票。投票完成后,标志就设置好了。
基于 Bidhan 的回答,您可以实现如下内容:
class Upvote(Model):
user = ForeignKeyField(User)
post = ForeignKeyField(Post)
class Meta:
indexes = (
(('user', 'post'), True), # Unique index on user+post
)
您可以将方法添加到 post:
def add_vote(self, user):
try:
with DATABASE.atomic():
Vote.create(user=user, post=self)
except IntegrityError:
return False # User already voted
else:
return True # Vote added
def num_votes(self):
return Vote.select().where(Vote.post == self).count()
也只是一个提示,但是您可以使用 atomic
而不是 transaction
,因为前者支持嵌套。