Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

calling append() on a ListField changes the default value #50

Open
lingthio opened this issue Sep 3, 2017 · 1 comment
Open

calling append() on a ListField changes the default value #50

lingthio opened this issue Sep 3, 2017 · 1 comment

Comments

@lingthio
Copy link

lingthio commented Sep 3, 2017

Thanks for this great package!

On object creation, where:

  • an attribute's Field.default has been defined, and
  • an attribute value is not specified in **kwargs

the object is created with this attribute value set to the Field.default.

For ListField attributes, this causes a problem, because list operations such as
append() will modify the Field.default and subsequent object creations will
behave unexpectedly.

I have included a code illustration below.

The obvious fix is to always initialize an object with a COPY of the Field.default.

from flask import Flask
from flask_mongoalchemy import MongoAlchemy

# Setup Flask
app = Flask(__name__)

# Setup MongoAlchemy
app.config.update(MONGOALCHEMY_DATABASE='issue_db')
db = MongoAlchemy(app)

# Define Item Document
class Item(db.Document):
    name = db.StringField(default='')
    colors = db.ListField(db.StringField(), default=[])

# Clear Item collection
db.session.clear_collection(Item)

# Create Documents
item1 = Item(name='Item One')
db.session.add(item1)
# item1.colors.append() modifies the Field default
item1.colors.append('red')
item1.colors.append('blue')

item2 = Item(name='Item Two')
db.session.add(item2)
db.session.flush()

# item2 is created with the modified Field default
assert item2.colors==[], 'item2.colors='+str(item2.colors)+' instead of []'

If users are looking for a temporary workaround:

item1.colors = item1.colors + ['red']  # this ensures a copy is assigned
item1.colors = item1.colors + ['blue']  # this ensures a copy is assigned
@fsouza
Copy link
Contributor

fsouza commented Sep 4, 2017

Hey @lingthio, thanks for reporting. Unfortunately, this is an issue in mongoalchemy itself. We can fix it on flask-mongoalchemy, but ideally this would be a fix upstream.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants