Closed mfrasca closed 12 years ago
By default, both primary and foreign keys are not displayed - only relations and "normal" data fields.
If you want to display primary key or foreign key, you have to explicitly list it in the list_columns
property.
aha, I see. by the way, the part that handles relationships is quite nice!
I could not find how to specify the list_columns
without creating a subclass of the ModelView
. is it possible, and documented? although, well, maybe I do want to subclass it, as I do not really care seeing the value of the key while viewing the data but I do need see it when I edit it!
Official way to do it is to subclass and implement necessary functionality. For example, if you have custom authentication and want to pass some parameters through constructor, do something like:
class MyModelView(ModelView):
def __init__(self, model, session, name=None, category=None, endpoint=None, url=None, **kwargs):
for k, v in kwargs.iteritems():
setattr(self, k, v)
super(MyModelView, self).__init__(model, session, name=name, category=category, endpoint=endpoint, url=url)
def is_accessible(self):
# Logic
return True
So when you use your MyModelView class to add administrative views, you can pass necessary parameters to the constructor:
admin.add_view(MyModelView(User, session, list_columns=['id', 'name', 'foreign_key']))
I understand I can do that, but it would be nice if the module would allow me to inform it that the primary key has to be shown. in some databases users rely on automatically defined numerical primary keys, then it is quite reasonable not showing them! but when a primary key is a significant code, like a person's fiscal code (which can be text or numeric), then it's a bit of a pity that flask-admin requires me to program a whole class just to tell it it should show the value of the primary key.
it would be easier if there was a parameter like please_do_show_primary_keys_value
that I can set to True
. right, maybe a bit less verbose.
column_display_pk: Feature or failure?
In the example given here: https://github.com/mrjoes/flask-admin/blob/master/examples/sqla/simple.py I have put "column_display_pk = True" in the UserAdmin class like that:
class UserAdmin(sqlamodel.ModelView): column_display_pk = True inline_models = (UserInfo,)
The primary key appears in the list of the "User" menu (there is just a tiny problem with the columns when I try to sort each one of them, but nothing serious). The problem is in the "Create" sub-menu. When I want to create a new User, the key is not showned, so I can't define it. Here it's ok because it's a technical key, but imagine it's a functional key (a text, for example), I can't define it, so I can't create a new Item (the key is not automatically generated and as no value).
I don't see the point of not automatically allow definition of the key with "column_display_pk = True" (if it's wanted), because if I want to see it, it's because it means something, so I do want to decide it's value at creation.
What I was expecting with "column_display_pk = True":
I don't know if the behaviour I noticed is a bug or is wanted, but I hope I'm clear enough about my expectation about functional keys.
column_display_pk
only affects list view.
If you want editable id
column in form, use additional form_columns
property and put id
in there:
class MyModel(ModelView):
column_display_pk = True
form_columns = ('id', 'name', 'text')
Overall, if you see variable with column_
prefix, it only affects list view. If with form_
prefix - it is form related.
Ok, thanks, it works just fine on creation. The problem is that on this configuration, it's possible to change the key in the edit formular, which is definitly not a best practice.
Flask-Admin manages create and edit forms separately.
You can override get_edit_form
: https://github.com/mrjoes/flask-admin/blob/master/flask_admin/model/base.py#L570
And do something like:
class MyView(ModelView):
def get_edit_form(self):
form = self.scaffold_form()
delattr(form, 'id')
return form
Or you can override get_create_form
and contribute id
field, etc.
That works, thanks, but I can't see the id in the edit_form (which is not a big deal because the object has already been chosen, but it's a pity however).
And with all your explanations, I will be able to build a super ModelView class with the name of the key as a parameter to regroup all those configurations.
May I just make a proposal: as you are able to automatically detect the primary-key for "column_display_pk", could you add in sqlamodel.ModelView a keyword like "functional_key_management" (= True) for example, to abstract all those configurations in one, as they are building a coherent whole: the management of a functional key.
Has this issue actually being resolved? I am looking into using flask-admin as my flask web app managing interface instead of writing editing pages for each database object, but unable to specify primary key when creating new object makes this task impossible.
I think a parameter form_display_pk = True should do, and the editing template should just make primary key field not editable.
also upvoting here for simple, out of the box option to show the primary key(s). having to write code for this basic functionality is needlessly complicated.
from ..models import User, UserGroup, Group, Role, PolicyRole, Cluster, Policy
class MfmdView(ModelView):
def __init__(self, model, session, name=None, category=None, endpoint=None, url=None, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
super(MfmdView, self).__init__(model, session, name=name, category=category, endpoint=endpoint, url=url)
def is_accessible(self):
return True
def model_list_columns(class_name):
list_columns = list()
for attr_key in class_name.__dict__.keys():
if not attr_key.startswith("_"):
list_columns.append(attr_key)
return list_columns
def model_link_view(model_list):
for model in model_list:
admin.add_view(MfmdView(model, db.session, column_list=model_list_columns(model)))
model_link_view([User, UserGroup, Group, Role, PolicyRole, Cluster, Policy])
This also works well
Just add:
column_display_pk = True
The solution that worked for me was subclassing ModelView
and overriding its constructor.
class AdminView(ModelView):
def __init__(self, model, *args, **kwargs):
self.column_list = [c.key for c in model.__table__.columns]
self.form_columns = self.column_list
super(AdminView, self).__init__(model, *args, **kwargs)
To show the primary key in list view, use column_display_pk
, like this:
class MyModelView(BaseModelView):
column_display_pk = True
Documentation: https://flask-admin.readthedocs.io/en/latest/api/mod_model/#flask_admin.model.BaseModelView.column_display_pk
not sure whether this is a bug report or just a question.
regarding the visibility of primary keys.
working: I have a table (Country) with automatic integer primary key and a table (Country_division) referring to it. When I insert a country_division in its table, the interface allows me to select a country. I never see the value of the primary key, but it works.
not working: I have a table (rank) with string primary key that is manually assigned. as above, I cannot see the column in the interface, but this is now a problem, because I can't specify the key manually.
since I'm still giving form to the database, I can consider falling back to automatic integer primary keys.