So I have this simple polling application that continuously create polls that people can vote +1 or -1 on. However, since this website doesn't require user logins people can vote multiple of times on every poll.
<form name="poll" id='{{ item.id }}' method="post" action='/poll'>
<label class='lab-pos'>
<input type="radio" name="points" id='whine-pos' value=1>
<img class='img-pos'src="/static/item-pos.png">
</label>
<label class='lab-neg'>
<input type="radio" name="points" id='whine-neg' value=-1>
<img class='img-neg'src="/static/item-neg.png">
</label>
</form>
I am sending the submit with a javascript function to my sqlite3 database, there is no submit button but the script.
<script type="text/javascript">
$(document).ready(function() {
$('input[type=radio]').on('change', function() {
$(this).closest("form").submit();
});
});
</script>
Is it possible to save the the votes in cookies with flask so when a person visits the site again they will not be able to vote again but only change the vote? (if they want). I know they can just clear cookies and they can vote again but that doesn't really bothers me in this phase.
My database structure in SQLAlchemy looks like this at the moment, and my view in flask like below
class pollingresult(db.Model):
__tablename__ = "pollingresult"
id = db.Column('id', db.Integer, primary_key=True)
poll = db.Column('poll', db.Integer)
cookie = db.Column('cookie', db.String(255))
feed_id = db.Column('feed_id', db.Integer)
def __init__(self, poll):
self.poll = poll
and my view in flask like below
@app.route('/poll', methods=['GET', 'POST'])
def poll():
polltodb = pollingresult(request.form['points'])
session['points_session'] = request.form['points']
db.session.add(polltodb)
db.session.commit()
return ('',204)
I have played around with the session but it seems that on refresh the polls are still getting 'rested' so people can vote again.
So, I am still struggling with this task, I can save the session['points_session'] to a session, but I need to save the session more like a dict, where the dict has id = item.id and points = points so I can prefill the forms with javascript 'if id = 1 and point = 1' prefill form with id = 1. I also need to prevent the form to be submitted again based on the session, so I guess i will have to create a somewhat dummy token for some kind of session key?
So I would like to send the poll_id along with the form submit so I thought I could use an ajax post request, however, this throws the error "Failed to decode JSON object: No JSON object could be decoded".
<script type="text/javascript">
$(document).ready(function() {
$('input[type=radio]').on('change', function() {
$(this).closest("form").submit();
var poll_id = $(this).closest("div").attr("id");
var data = {poll_id};
console.log(JSON.stringify(data));
$.post('/poll', {
data: JSON.stringify(data),
}, function(data) {
console.log(data);
});
});
});
</script>
Along with the new poll route:
@app.route('/poll', methods=['GET', 'POST'])
def poll():
polltodb = pollingresult(request.form['points'])
session['points_session'] = request.form['points']
db.session.add(polltodb)
db.session.commit()
data = request.get_json(force=True)
print data
return ('',204)
This will later be inserted into the DB along with some kind of session key.
Instead of saving the polls the user has voted on in their session, simply attach a "poll_user_id" to the session so you can keep track of the user and their votes in the database.
from uuid import uuid1 as uuid
if "poll_user_id" not in session:
session["poll_user_id"] = uuid()
Here's some psuedo code as I'm not familar with Flask and their database engine.
old_vote = query(poll_user_id=session["poll_user_id"], poll=poll_id)
if not old_vote:
insert(poll_user_id=session["poll_user_id"], poll=poll_id, choice=form.choice)
else:
update(poll_user_id=session["poll_user_id"], poll=poll_id, choice=form.choice)
Now, when a user votes, either new or as an update, it checks if a vote already exists with the same "poll_user_id" value, if it does you'll do an update. If it doesn't do an insert.
i would suggest you don't use cookies at all. I use browser fingerprinting to identify users. The advantage is that you can id them even if they open the page in incognito again and again (which would clear all your cookies / sessions)
https://clientjs.org/#Fingerprints
You would be better off generating a (admittedly semi-unique) fingerprint and tracking duplicate user's this way. I have been using this with good success and i have a link where the user can flag that he has not completed the vote/action and i have not
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With