I'm setting up a flask application to run an anonymous online experiment. How can I track anonymous participants via the the current_user object of the Login-manager?
When a user is anonymous the current_user is set to AnonymousUserMixin. I tried to assign AnonymousUserMixin an id variable (through uuid.uuid4() for instance) to not have current_user=None but then it's not an ORM object anymore. I tried to follow the advice of the second answer of this post (How to track anonymous users with Flask), but I'm lacking knowledge how to transform the described way into actual code.
So I ended up with the error message 'AnonymousUserMixin' object has no attribute '_sa_instance_state' which I can't seem to get solved.
Any suggestions on how to use the current_user object with anonymous users?
Here some relevant code parts [EDIT: code was adjusted based on @Roch's suggestion] :
models.py
from website import db
# models for database structure
class DemographicData(db.Model):
__tablename__ = 'demographic_data'
id = db.Column(db.Integer, primary_key=True)
gender = db.Column(db.String(1), nullable=False)
age = db.Column(db.Integer, nullable=False)
nationality = db.Column(db.String(50), nullable=False)
# create relationships to the other models to link them to the demographicData
consentRequest = db.relationship('ModalData', backref='participant_bref', lazy=True)
def __repr__(self):
return f"demographicData('{self.id}', '{self.gender}', '{self.age}', '{self.nationality}')"
class ModalData(db.Model):
__tablename__ = 'modal_data'
id = db.Column(db.Integer, primary_key=True)
participantId = db.Column(db.Integer, db.ForeignKey('demographic_data.id'), nullable=False)
consent = db.Column(db.String(3), nullable=False)
def __repr__(self):
return f"modalData('{self.participantId}', '{self.consent}')"
routes.py
from flask import render_template, url_for, redirect, request, session
from website import app, db
from website.models import DemographicData, ModalData
from website.questionnaires import DemographicsForm
@app.before_request
def make_session_permanent():
session.permanent = True
# route to demographic information form
@app.route("/demographics", methods=['GET', 'POST'])
def demographics():
form = DemographicsForm()
if form.validate_on_submit():
participant = DemographicData(gender=form.gender.data,
age=form.age.data,
nationality=form.nationality.data)
session['anonymous_user_id'] = participant.id
# save to database
db.session.add(participant)
db.session.commit()
return redirect(url_for('megazine'))
return render_template('demographics.html', title='Demographic Information', form=form)
# route to a website I want to redirect to after demographics
@app.route("/megazine", methods=['GET', 'POST'])
def megazine():
if request.method == 'POST':
consentDecision = ModalData(participant_bref=session['anonymous_user_id'],
consent=request.form['consentForm'])
db.session.add(consentDecision)
db.session.commit()
return redirect(url_for('motivemag'))
return render_template('/newswebsite_templates/megazine/index.html', title='Megazine')