-1

I am attempting to use the append method to add to a reference table for a many-to-many relationship between class User and class App (also referred to as 'plus' throughout the code). The idea is that there will be many users who use a single app and many apps used by a single user so I thought a many to many relationship would be appropriate. I am able to get a valid user object and a valid app/plus object but when I use plus.append(user), nothing happens. I don't get an error and nothing is added to the reference table. I am guessing I did not set up the relationship correctly?

Things I've tried:

  • Changing the direction of the relationship so User is the left side entity.
  • Making it into a one to many relationship.
  • The bi-directional example given in the documentation here.
  • The solution here.

Reference table definition:

plusses = db.Table(
'plusses',
db.Column('plus_id', db.Integer, db.ForeignKey('app.id')),
db.Column('user_id', db.Integer, db.ForeignKey('user.id')))

Definition of 'User' class

class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
about_me = db.Column(db.String(140))
last_seen = db.Column(db.DateTime, default=datetime.utcnow)

Definition of 'App' class:

class App(db.Model):
id = db.Column(db.Integer, primary_key=True)
icon = db.Column(db.String(140))
link = db.Column(db.String(140))
name = db.Column(db.String(140))
args = db.Column(db.Text())
description = db.Column(db.String(220))

pluses_user = db.relationship(
        'User', secondary=plusses,backref=db.backref('plusses', lazy='dynamic'), lazy='dynamic')


def __repr__(self):
    return '<App {}>'.format(self.body)

def getApp(self, name):
    return App.query.filter_by(name=name).first()
    # if app is None:
        # Create app here if

def add_plus(self, user):
    if not self.has_plus(user):
        self.pluses_user.append(user)

def remove_plus(self, user):
    if self.has_plus(user):
        self.pluses_user.remove(user)

def has_plus(self, user):
    return self.pluses_user.filter(
        plusses.c.plus_id == user.id).count() > 0

Route that uses the function:

@bp.route('/add/<plusname>')
@login_required
def add_plus(plusname):
  plus=App.query.filter_by(name=plusname).first()
  if plus is None:
      flash('App not found')
      return redirect(url_for('main.index'))
  plus.add_plus(current_user)
  return redirect(url_for('main.apps'))

I'm new here so please let me know how I can improve my question :) Any help at all would be appreciated.

1 Answers1

1

I was able to solve this by adding db.session.commit() to my add_plus and remove_plus functions. They now look like this:

def add_plus(self, user):
    if not self.has_plus(user):
        self.pluses_user.append(user)
        db.session.commit()

def remove_plus(self, user):
    if self.has_plus(user):
        self.pluses_user.remove(user)
        db.session.commit()
Dharman
  • 30,962
  • 25
  • 85
  • 135