Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>The cause of the problem</h2> <p>The crux of your problem is that <strong>SQL Alchemy is expecting the <code>permissions</code> relationship to be populated with sqlalchemy <code>permission</code> objects, not the <code>int</code>s you are passing it</strong>.<br> In your view: </p> <pre><code>form = EditUser(request.form, obj=user) form.permissions.choices = [(p.id, p.perm) for p in Permission.query.order_by('perm')] form.permissions.data = [p.id for p in user.permissions] </code></pre> <p>So in your form, <code>form.permissions</code> is actually just holding the <code>id</code> (int) of the permission object's, not the objects themselves. When you call <code>form.populate_obj(user)</code>, when it gets to the permissions segment, its going to call this method: </p> <p><code>setattr(obj, name, self.data)</code> </p> <p>Which translates to: </p> <p><code>setattr(user, permissions, sefl.data)</code> </p> <p>Which translates to: </p> <p><code>user.permissions = [1, 3, 4 ...]</code> </p> <p>But SQL Alchemy expects: </p> <p><code>user.permissions = [sqlalchemyobject1, sqlalchemyobject2, ...]</code> </p> <h2>Solution</h2> <p>There are at least a few ways to solve this problem. The method I use is sqlalchemy's <a href="http://docs.sqlalchemy.org/en/rel_0_7/orm/extensions/associationproxy.html">Association Proxy</a>. This will let you do things like pass a list of integers to your user model, and <strong>have the Model convert them to Permissions objects</strong>: </p> <pre><code>class User(db.Model): ... permissions_relationship = ('Permission', cascade="all,delete,delete-orphan") permissions = association_proxy('permissions_relationship', 'perm', creator=lambda perm: Permission(perm=perm) class Permission(db.Model): ... perm = ... def __init__(self,perm): self.perm = perm </code></pre> <p>In a Nutshell, the <code>association_proxy</code> call simply says: "When you get passed a list of items (Ints, Strings, whatever), convert them to <code>Permission</code> objects by doing this: <code>Permission(perm=perm)</code>. Using this solution in your above code, you would remove the line <code>form.permissions.data = [p.id for p in user.permissions]</code>. </p> <p>Finally, <code>wtforms</code> also provides a <a href="http://wtforms.simplecodes.com/docs/1.0.2/ext.html#wtforms.ext.sqlalchemy.fields.QuerySelectMultipleField">QuerySelectMultiple field</a>. I haven't used it, but imagine it would also serve as a solution to this problem. </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload