internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: flask-admin/flask-admin

Issue:
Why does form_choices use column.key instead of prop.key
Hi Everybody,

I was trying to use form_choices, to modify choices displayed for an enum field in my DB like this:

```
class FieldModelView(ModelView):
    list_columns = ['label', 'field_type', 'description']
    form_columns = ['label', 'field_type', 'description']
    form_choices = {'field_type': ['choice1', 'choice2', 'choice3', 'choice4', 'choice5']
```

the problem is that form_choices wasn't working and when I checked the code of flask admin, i founded that form_choices is checked using column.key instead of prop.key. So if our name in the database is different from our property name in ORM class, form_choices doesn't found the property, and doesn't change choices of our selecfield.



Discussion:

Resolving patch:
diff --git a/flask_admin/contrib/sqla/form.py b/flask_admin/contrib/sqla/form.py
--- a/flask_admin/contrib/sqla/form.py
+++ b/flask_admin/contrib/sqla/form.py
@@ -243,7 +243,7 @@ def convert(self, model, mapper, name, prop, field_args, hidden_pk):
             form_choices = getattr(self.view, 'form_choices', None)
 
             if mapper.class_ == self.view.model and form_choices:
-                choices = form_choices.get(column.key)
+                choices = form_choices.get(prop.key)
                 if choices:
                     return form.Select2Field(
                         choices=choices,
@@ -537,7 +537,7 @@ def process_ajax_refs(self, info):
     def _calculate_mapping_key_pair(self, model, info):
         """
             Calculate mapping property key pair between `model` and inline model,
-                including the forward one for `model` and the reverse one for inline model. 
+                including the forward one for `model` and the reverse one for inline model.
                 Override the method to map your own inline models.
 
             :param model:


Test patch:
Repository: flask-admin/flask-admin

Issue:
Reflected XSS
We're using this framework internally within a flask app and a colleague noted a reflected XSS issue:

Example:
https://10.0.0.1/admin/user/edit/?url=%20javascript%3aalert(document.domain)&id=8

User interaction is required, when clicking the "List" link the javascript is executed.


Discussion:
The affected file appears to be https://github.com/flask-admin/flask-admin/blob/d57048b041c737f8f4b61f9a2260fc0607dff2aa/flask_admin/helpers.py
It looks like we're going to need a more robust version of `is_safe_url`.

It looks like django's handles it correctly:
```
>>> from django.utils.http import is_safe_url
>>> is_safe_url('/admin/car/')
True
>>> is_safe_url(' javascript:alert(document.domain)')
False
```

Their version of is_safe_url is pretty complex and I'm not sure which line is causing it to return false yet. Here's a link to the file it's in: https://github.com/django/django/blob/550cb3a365dee4edfdd1563224d5304de2a57fda/django/utils/http.py

Resolving patch:
diff --git a/flask_admin/helpers.py b/flask_admin/helpers.py
--- a/flask_admin/helpers.py
+++ b/flask_admin/helpers.py
@@ -8,6 +8,9 @@
 from ._compat import string_types
 
 
+VALID_SCHEMES = ['http', 'https']
+
+
 def set_current_view(view):
     g._admin_view = view
 
@@ -128,10 +131,16 @@ def prettify_class_name(name):
 
 
 def is_safe_url(target):
+    # prevent urls starting with "javascript:"
+    target = target.strip()
+    target_info = urlparse(target)
+    target_scheme = target_info.scheme
+    if target_scheme and target_scheme not in VALID_SCHEMES:
+        return False
+
     ref_url = urlparse(request.host_url)
     test_url = urlparse(urljoin(request.host_url, target))
-    return (test_url.scheme in ('http', 'https') and
-            ref_url.netloc == test_url.netloc)
+    return ref_url.netloc == test_url.netloc
 
 
 def get_redirect_target(param_name='url'):


Test patch:
diff --git a/flask_admin/tests/test_helpers.py b/flask_admin/tests/test_helpers.py
new file mode 100644
--- /dev/null
+++ b/flask_admin/tests/test_helpers.py
@@ -0,0 +1,17 @@
+import flask
+
+from flask_admin import helpers
+
+
+def test_is_safe_url():
+    app = flask.Flask(__name__)
+
+    with app.test_request_context('http://127.0.0.1/admin/car/edit/'):
+        assert helpers.is_safe_url('http://127.0.0.1/admin/car/')
+        assert helpers.is_safe_url('https://127.0.0.1/admin/car/')
+        assert helpers.is_safe_url('/admin/car/')
+        assert helpers.is_safe_url('admin/car/')
+
+        assert not helpers.is_safe_url('http://127.0.0.2/admin/car/')
+        assert not helpers.is_safe_url(' javascript:alert(document.domain)')
+        assert not helpers.is_safe_url('javascript:alert(document.domain)')
Repository: flask-admin/flask-admin

Issue:
Python 2.6 build is failing
SQLAlchemy 1.2 now requires Python 2.7 or higher: http://docs.sqlalchemy.org/en/latest/intro.html#supported-platforms, so the build is now failing.

For example: https://travis-ci.org/flask-admin/flask-admin/jobs/330586924#L733

What should we do? Use SQLAlchemy 1.1.x or drop Python 2.6 support too?


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -36,9 +36,6 @@ def grep(attrname):
     'wtforms'
 ]
 
-if sys.version_info[:2] < (2, 7):
-    install_requires.append('ordereddict')
-
 setup(
     name='Flask-Admin',
     version=grep('__version__'),
@@ -76,10 +73,10 @@ def grep(attrname):
         'Programming Language :: Python',
         'Topic :: Software Development :: Libraries :: Python Modules',
         'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 2.6',
         'Programming Language :: Python :: 3.3',
         'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
+        'Programming Language :: Python :: 3.6',
     ],
     test_suite='nose.collector'
 )


Test patch:
Repository: flask-admin/flask-admin

Issue:
Some methods should be properties in the User classes defined in the examples
In the examples auth-flask-login and auth-mongoengine, inside the `User` class, the methods: 
- `is_authenticated`
- `is_active`
- `is_anonymous` 

should be properties as they are being used like properties. See also: https://flask-login.readthedocs.io/en/latest/#your-user-class

Or am I missing something here?  


Discussion:
That was changed by Flask-Login in one of the recent (or relatively recent versions). Before that they were methods.
Thanks for the info @mrjoes! Seems to have been changed in 0.3.0, released on September 2015  (see. https://github.com/maxcountryman/flask-login/blob/master/CHANGES).

Would you like to have PR for this?

Resolving patch:
diff --git a/examples/auth-flask-login/app.py b/examples/auth-flask-login/app.py
--- a/examples/auth-flask-login/app.py
+++ b/examples/auth-flask-login/app.py
@@ -32,12 +32,17 @@ class User(db.Model):
     password = db.Column(db.String(64))
 
     # Flask-Login integration
+    # NOTE: is_authenticated, is_active, and is_anonymous
+    # are methods in Flask-Login < 0.3.0
+    @property
     def is_authenticated(self):
         return True
 
+    @property
     def is_active(self):
         return True
 
+    @property
     def is_anonymous(self):
         return False
 
diff --git a/examples/auth-mongoengine/app.py b/examples/auth-mongoengine/app.py
--- a/examples/auth-mongoengine/app.py
+++ b/examples/auth-mongoengine/app.py
@@ -27,12 +27,17 @@ class User(db.Document):
     password = db.StringField(max_length=64)
 
     # Flask-Login integration
+    # NOTE: is_authenticated, is_active, and is_anonymous
+    # are methods in Flask-Login < 0.3.0
+    @property
     def is_authenticated(self):
         return True
 
+    @property
     def is_active(self):
         return True
 
+    @property
     def is_anonymous(self):
         return False
 


Test patch:
Repository: flask-admin/flask-admin

Issue:
Add support for CITEXT type in column filters
 Adding `'citext'` to the following line in /flask_admin/contrib/sqla/filters.py should work

https://github.com/flask-admin/flask-admin/blob/38e5b8057cb1acce805b6f6bfa923897371588cc/flask_admin/contrib/sqla/filters.py#L374



Discussion:

Resolving patch:
diff --git a/flask_admin/contrib/sqla/filters.py b/flask_admin/contrib/sqla/filters.py
--- a/flask_admin/contrib/sqla/filters.py
+++ b/flask_admin/contrib/sqla/filters.py
@@ -373,7 +373,7 @@ def convert(self, type_name, column, name, **kwargs):
 
     @filters.convert('string', 'char', 'unicode', 'varchar', 'tinytext',
                      'text', 'mediumtext', 'longtext', 'unicodetext',
-                     'nchar', 'nvarchar', 'ntext')
+                     'nchar', 'nvarchar', 'ntext', 'citext')
     def conv_string(self, column, name, **kwargs):
         return [f(column, name, **kwargs) for f in self.strings]
 


Test patch:
Repository: flask-admin/flask-admin

Issue:
AttributeError: 'TypeError' object has no attribute 'message'
On Python 3.7:
```
  File "/Users/alex/.pyenv/versions/3.7.0/envs/api2/lib/python3.7/site-packages/flask_admin/contrib/sqla/view.py", line 1085, in create_model
    if not self.handle_view_exception(ex):
  File "/Users/alex/.pyenv/versions/3.7.0/envs/api2/lib/python3.7/site-packages/flask_admin/contrib/sqla/view.py", line 1068, in handle_view_exception
    return super(ModelView, self).handle_view_exception(exc)
  File "/Users/alex/.pyenv/versions/3.7.0/envs/api2/lib/python3.7/site-packages/flask_admin/contrib/sqla/view.py", line 1082, in create_model
    self._on_model_change(form, model, True)
  File "/Users/alex/.pyenv/versions/3.7.0/envs/api2/lib/python3.7/site-packages/flask_admin/model/base.py", line 1550, in _on_model_change
    if re.match(r'on_model_change\(\) takes .* 3 .* arguments .* 4 .* given .*', e.message):
AttributeError: 'TypeError' object has no attribute 'message'
```


Discussion:
This bug occurred on python3 when the exception doesn't contain 'message' attribute. Could I make a PR to fix this issue?
@dinhnv yes of course

Resolving patch:
diff --git a/flask_admin/model/base.py b/flask_admin/model/base.py
--- a/flask_admin/model/base.py
+++ b/flask_admin/model/base.py
@@ -1547,7 +1547,7 @@ def _on_model_change(self, form, model, is_created):
         try:
             self.on_model_change(form, model, is_created)
         except TypeError as e:
-            if re.match(r'on_model_change\(\) takes .* 3 .* arguments .* 4 .* given .*', e.message):
+            if re.match(r'on_model_change\(\) takes .* 3 .* arguments .* 4 .* given .*', str(e)):
                 msg = ('%s.on_model_change() now accepts third ' +
                        'parameter is_created. Please update your code') % self.model
                 warnings.warn(msg)


Test patch:
Repository: flask-admin/flask-admin

Issue:
FileAdmin can not download file similar 2018-10:32.csv file
when i feed base_url to FileAdmin construct function, then i can not download this file, 
when i run curl , i get this result.
![](http://caiji.scuseek.com/228dea07e6cde4ad3cf64a4368eaec24.png)
It's seem base_url not work for me
after this, I try to run official example, but it's work fine.
It give right 302 redirect.
I am confused, until i run code like below
![](http://caiji.scuseek.com/ebd35baa150012c371cd098d1b02c6da.png)
i want to know why this happen? and will it should be fixed by flask-admin?
FileAdmin can not download file similar 2018-10:32.csv file
when i feed base_url to FileAdmin construct function, then i can not download this file, 
when i run curl , i get this result.
![](http://caiji.scuseek.com/228dea07e6cde4ad3cf64a4368eaec24.png)
It's seem base_url not work for me
after this, I try to run official example, but it's work fine.
It give right 302 redirect.
I am confused, until i run code like below
![](http://caiji.scuseek.com/ebd35baa150012c371cd098d1b02c6da.png)
i want to know why this happen? and will it should be fixed by flask-admin?


Discussion:

Resolving patch:
diff --git a/flask_admin/_compat.py b/flask_admin/_compat.py
--- a/flask_admin/_compat.py
+++ b/flask_admin/_compat.py
@@ -38,7 +38,7 @@ def csv_encode(s):
 
     # Various tools
     from functools import reduce
-    from urllib.parse import urljoin, urlparse
+    from urllib.parse import urljoin, urlparse, quote
 else:
     text_type = unicode
     string_types = (str, unicode)
@@ -62,6 +62,7 @@ def csv_encode(s):
     # Helpers
     reduce = __builtins__['reduce'] if isinstance(__builtins__, dict) else __builtins__.reduce
     from urlparse import urljoin, urlparse
+    from urllib import quote
 
 
 def with_metaclass(meta, *bases):
diff --git a/flask_admin/contrib/fileadmin/__init__.py b/flask_admin/contrib/fileadmin/__init__.py
--- a/flask_admin/contrib/fileadmin/__init__.py
+++ b/flask_admin/contrib/fileadmin/__init__.py
@@ -12,7 +12,7 @@
 from wtforms import fields, validators
 
 from flask_admin import form, helpers
-from flask_admin._compat import urljoin, as_unicode
+from flask_admin._compat import urljoin, as_unicode, quote
 from flask_admin.base import BaseView, expose
 from flask_admin.actions import action, ActionsMixin
 from flask_admin.babel import gettext, lazy_gettext
@@ -944,7 +944,7 @@ def download(self, path=None):
         base_url = self.get_base_url()
         if base_url:
             base_url = urljoin(self.get_url('.index_view'), base_url)
-            return redirect(urljoin(base_url, path))
+            return redirect(urljoin(quote(base_url), quote(path)))
 
         return self.storage.send_file(directory)
 


Test patch:
Repository: flask-admin/flask-admin

Issue:
Search field placeholder translation not showing
This is a regression caused by #1278


Discussion:

Resolving patch:
diff --git a/examples/sqla/app.py b/examples/sqla/app.py
--- a/examples/sqla/app.py
+++ b/examples/sqla/app.py
@@ -197,10 +197,16 @@ class PostAdmin(sqla.ModelView):
     column_labels = dict(title='Post Title')  # Rename 'title' column in list view
     column_searchable_list = [
         'title',
-        User.first_name,
-        User.last_name,
         'tags.name',
+        'user.first_name',
+        'user.last_name',
     ]
+    column_labels = {
+        'title': 'Title',
+        'tags.name': 'tags',
+        'user.first_name': 'user\'s first name',
+        'user.last_name': 'last name',
+    }
     column_filters = [
         'user',
         'title',
diff --git a/flask_admin/contrib/sqla/view.py b/flask_admin/contrib/sqla/view.py
--- a/flask_admin/contrib/sqla/view.py
+++ b/flask_admin/contrib/sqla/view.py
@@ -590,10 +590,10 @@ class MyModelView(BaseModelView):
                 column_labels = dict(name='Name', last_name='Last Name')
                 column_searchable_list = ('name', 'last_name')
 
-            placeholder is: "Search: Name, Last Name"
+            placeholder is: "Name, Last Name"
         """
         if not self.column_searchable_list:
-            return 'Search'
+            return None
 
         placeholders = []
 
@@ -605,7 +605,7 @@ class MyModelView(BaseModelView):
                 placeholders.append(
                     self.column_labels.get(searchable, searchable))
 
-        return 'Search: %s' % u', '.join(placeholders)
+        return u', '.join(placeholders)
 
     def scaffold_filters(self, name):
         """
diff --git a/flask_admin/model/base.py b/flask_admin/model/base.py
--- a/flask_admin/model/base.py
+++ b/flask_admin/model/base.py
@@ -1109,9 +1109,9 @@ def init_search(self):
 
     def search_placeholder(self):
         """
-            Return search placeholder.
+            Return search placeholder text.
         """
-        return 'Search'
+        return None
 
     # Filter helpers
     def scaffold_filters(self, name):


Test patch:
Repository: flask-admin/flask-admin

Issue:
Regression: Batch actions not working
On the master branch, batch actions fail with a JS error: `TypeError: undefined is not an object (evaluating 'modelActions.execute')`


Discussion:

Resolving patch:
diff --git a/examples/sqla/app.py b/examples/sqla/app.py
--- a/examples/sqla/app.py
+++ b/examples/sqla/app.py
@@ -145,6 +145,7 @@ def operation(self):
 }
 
 class UserAdmin(sqla.ModelView):
+    action_disallowed_list = ['delete', ]
     column_display_pk = True
     column_list = [
         'id',


Test patch:
Repository: flask-admin/flask-admin

Issue:
"examples" package erroneously installed
Because there's an `examples/__init__.py` file in the repo, [this line of setup.py](https://github.com/flask-admin/flask-admin/blob/08bdcdea27fed6dcef7627bf7d2ac0625c4c2a9c/setup.py#L54) is erroneously deciding to install two packages, `flask-admin` and `examples`. I suspect other packages make this same mistake, which can lead to some file conflicts during installation.

It would be best to either change your `find_packages` invocation to blacklist `exclude`:

```python
find_packages(exclude=['examples', 'examples.*'])
```

Or (and this is how I would do it to avoid this problem in the future) or to whitelist `flask_admin`:

```python
find_packages(include=['flask_admin'])
```

I would also go further and also blacklist `flask_admin.tests`, since I think tests should not be part of the installation:

```python
find_packages(include=['flask_admin'], exclude=['flask_admin.tests.*'])
```

But I think just not shipping the `examples` package is a good start.


Discussion:
Sounds good. The `include` option won't work as all "batteries" are shipped as `flask_admin.contrib` sub-packages.

But sure, examples and tests can be safely removed.
@mrjoes I always get these `find_packages` things confused. I think the "include" version is actually:

```python
find_packages(include=['flask_admin', 'flask_admin.*'])
```

Though for some reason adding `exclude=['flask_admin.tests.*']` doesn't remove the `flask_admin.tests` module. Not entirely sure what's up with that.

Another, more radical perspective to consider might be using the `src` layout, which [Hynek Schlawack compellingly argues for here](https://hynek.me/articles/testing-packaging/). A less radical version of that is moving `flask_admin/tests` into a `tests` directory alongside `flask_admin`, though that would still probably entail quite a bit of refactoring (haven't looked at the code myself to check this).

Probably the easy thing to do is start by blacklisting and then revisit a whitelist later.
This is a substantial issue for a project I'm working on. The `examples` package installed alongside `flask-admin` is overwriting our project's `examples` package.

Is there any way I could speed up the fix? Happy to do a PR if that would help.

Resolving patch:
diff --git a/examples/__init__.py b/examples/__init__.py
deleted file mode 100644


Test patch:
Repository: flask-admin/flask-admin

Issue:
x-editable Boolean in list view doesn't update after editing
When editing a boolean value in the list view (i.e. `column_editable_list = ['is_active', ]`, the field can be edited, but the new value is only shown after a page refresh.


Discussion:

Resolving patch:
diff --git a/flask_admin/model/widgets.py b/flask_admin/model/widgets.py
--- a/flask_admin/model/widgets.py
+++ b/flask_admin/model/widgets.py
@@ -110,6 +110,7 @@ def get_kwargs(self, field, kwargs):
             kwargs['data-rows'] = '5'
         elif field.type == 'BooleanField':
             kwargs['data-type'] = 'select2'
+            kwargs['data-value'] = '1' if field.data else ''
             # data-source = dropdown options
             kwargs['data-source'] = json.dumps([
                 {'value': '', 'text': gettext('No')},


Test patch:
Repository: flask-admin/flask-admin

Issue:
Documentation for contrib.sqla.ModelView.get_query should mention overriding get_one
The documentation for [contrib.sqla.ModelView.get_query](https://flask-admin.readthedocs.io/en/latest/api/mod_contrib_sqla/#flask_admin.contrib.sqla.ModelView.get_query) reminds the user to override `get_count_query` as well. It should also mention to override `get_one` as well, for example like this:

```python
def get_one(self, id):
    """Return an element with limited to the elements returned by get_query."""
    query = self.get_query()
    return query.filter(self.model.id == id).first()
```

If it is not done this way, some elements might be filtered in the list view, but can still be accessed in the edit view by simply changing the id in the url. This potentially allows users to see/edit elements they should not be allowed to see/edit.


Discussion:
Thanks @lapseofreason. Could you make a pull request?

Resolving patch:
diff --git a/flask_admin/contrib/sqla/view.py b/flask_admin/contrib/sqla/view.py
--- a/flask_admin/contrib/sqla/view.py
+++ b/flask_admin/contrib/sqla/view.py
@@ -833,6 +833,17 @@ def get_query(self):
                 class MyView(ModelView):
                     def get_query(self):
                         return super(MyView, self).get_query().filter(User.username == current_user.username)
+
+            Individual elements that are filtered in the list view are still
+            accessible through the edit view by simply changing the URL, even
+            when they are filtered by `get_query`. To prohibit this, also
+            override `get_one`.
+
+            Example::
+
+                def get_one(self, id):
+                    query = self.get_query()
+                    return query.filter(self.model.id == id).first()
         """
         return self.session.query(self.model)
 
@@ -1073,6 +1084,8 @@ def get_one(self, id):
         """
             Return a single model by its id.
 
+            Also see `get_query` for how to filter the list view.
+
             :param id:
                 Model id
         """


Test patch:
Repository: flask-admin/flask-admin

Issue:
flask-admin doesn't work on Python 2.7
Running flask-admin version `1.5.2` on Python `2.7` fails with 
```
File "/usr/local/lib/python2.7/site-packages/flask_admin/contrib/sqla/form.py", line 2, in <module>
    from enum import Enum
ImportError: No module named enum
```
Does flask-admin supports Python 2.7 ?

The issue is line https://github.com/flask-admin/flask-admin/blob/829c24dbe4da9e28f705d07608e3326e4ff0b209/flask_admin/contrib/sqla/form.py#L2 

I fixed the issue by installing `enum34` package. flask-admin should have `enum34` as it's dependency for python versions smaller than 3.4



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -42,6 +42,11 @@ def grep(attrname):
     'wtforms'
 ]
 
+if sys.version_info[0:2] < (3, 4):
+    # required for python < 3.4
+    install_requires.append('enum34>=1.1.6')
+
+
 setup(
     name='Flask-Admin',
     version=grep('__version__'),


Test patch: