-
Notifications
You must be signed in to change notification settings - Fork 8
Commit v0.33
kwmccabe edited this page Apr 17, 2018
·
8 revisions
v0.33 - Refactor item.active as item.item_status
- +6 -6 [M] mysql/scripts/seeddata.sql
- +2 -2 [M] mysql/scripts/tables.sql
- +18 -18 [M] web/app/decorators.py
- +17 -10 [M] web/app/item/forms.py
- +27 -27 [M] web/app/item/models.py
- +8 -3 [M] web/app/item/templates/item_edit.html
- +26 -17 [M] web/app/item/templates/item_list.html
- +14 -3 [M] web/app/item/templates/item_view.html
- +19 -18 [M] web/app/item/views.py
- +5 -5 [M] web/app/user/forms.py
- +3 -3 [M] web/app/user/templates/user_edit.html
- +5 -4 [M] web/app/user/templates/user_list.html
- +1 -1 [M] web/app/user/templates/user_view.html
- +17 -17 [M] web/app/user/views.py
- +11 -0 [M] web/config.py
- Add
item_status
column to test data.
DELETE FROM `item`;
-INSERT INTO `item` (keyname,item_title,item_text) VALUES ("one","One","One here");
-INSERT INTO `item` (keyname,item_title,item_text) VALUES ("two","Two","Two here");
-INSERT INTO `item` (keyname,item_title,item_text) VALUES ("three","Three","Three here");
-INSERT INTO `item` (keyname,item_title,item_text) VALUES ("four","Four","Four here");
-INSERT INTO `item` (keyname,item_title,item_text) VALUES ("five","Five","Five here");
-INSERT INTO `item` (keyname,item_title,item_text) VALUES ("six","Six","Six here");
+INSERT INTO `item` (item_status,keyname,item_title,item_text) VALUES (3,"one","One","One here");
+INSERT INTO `item` (item_status,keyname,item_title,item_text) VALUES (2,"two","Two","Two here");
+INSERT INTO `item` (item_status,keyname,item_title,item_text) VALUES (1,"three","Three","Three here");
+INSERT INTO `item` (item_status,keyname,item_title,item_text) VALUES (0,"four","Four","Four here");
+INSERT INTO `item` (item_status,keyname,item_title,item_text) VALUES (3,"five","Five","Five here");
+INSERT INTO `item` (item_status,keyname,item_title,item_text) VALUES (3,"six","Six","Six here");
OPTIMIZE TABLE `item`;
- Rename
active
column asitem_status
.
DROP TABLE IF EXISTS `item`;
CREATE TABLE `item` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
- `active` tinyint(1) NOT NULL DEFAULT '1',
`keyname` varchar(63) NOT NULL,
+ `item_status` tinyint(1) NOT NULL DEFAULT '1',
`item_title` varchar(255) DEFAULT NULL,
...
UNIQUE KEY `item_keyname` (`keyname`),
- KEY `item_active` (`active`),
+ KEY `item_status` (`item_status`),
KEY `item_title` (`item_title`),
- Remove previous
status
string param. - Create new
item_status
integer param.
logging.debug('create session[%s]' % (session_key))
session[session_key] = { \
- 'itemcnt' : 0, \
- 'pagecnt' : 0, \
- 'status' : 'all', \
- 'user_role' : -1, \
- 'sort' : 'id', \
- 'order' : 'asc', \
- 'offset' : 0, \
- 'limit' : 10, \
- 'page' : 1, \
+ 'itemcnt' : 0, \
+ 'pagecnt' : 0, \
+ 'user_role' : -1, \
+ 'item_status' : -1, \
+ 'sort' : 'id', \
+ 'order' : 'asc', \
+ 'offset' : 0, \
+ 'limit' : 10, \
+ 'page' : 1, \
}
# get updates
S = session[session_key]
- status = request.values.get('status', S['status'])
- user_role = request.values.get('user_role', S['user_role'])
- sort = request.values.get('sort', S['sort'])
- order = request.values.get('order', S['order'])
- limit = int(request.values.get('limit', S['limit']))
- page = int(request.values.get('page', S['page']))
+ user_role = request.values.get('user_role', S['user_role'])
+ item_status = request.values.get('item_status', S['item_status'])
+ sort = request.values.get('sort', S['sort'])
+ order = request.values.get('order', S['order'])
+ limit = int(request.values.get('limit', S['limit']))
+ page = int(request.values.get('page', S['page']))
- if status in ['all','active','inactive']:
- S['status'] = status
- if user_role in ['-1','0','1','2','3']:
+ if user_role in [-1,0,1,2,3]:
S['user_role'] = int(user_role)
+ if item_status in [-1,0,1,2,3]:
+ S['item_status'] = item_status
- Replace
active
BooleanField withitem_status
SelectField. - Populate select options in
__init__()
usingcurrent_app.config['ITEM_STATUS']
and related values.
+from flask import current_app
...
class EditItemForm(FlaskForm):
- id = HiddenField('id')
- keyname = StringField('Keyname', validators=[InputRequired(),Length(2,63),validate_keyname], filters=[filter_keyname])
- active = BooleanField('Active')
- item_title = StringField('Title', validators=[InputRequired(),Length(1,255)])
- item_text = TextAreaField('Text')
- mod_create = DateTimeField('Item Created')
- mod_update = DateTimeField('Item Updated')
- owner_id = SelectField('Item Owner', choices=[], coerce=int)
- users_id = SelectMultipleField('Editors', choices=[], coerce=int)
- submit = SubmitField('Update Item')
+ id = HiddenField('id')
+ keyname = StringField('Keyname', validators=[InputRequired(),Length(2,63),validate_keyname], filters=[filter_keyname])
+ item_status = SelectField('Item Status', choices=[], coerce=int)
+ item_title = StringField('Title', validators=[InputRequired(),Length(1,255)])
+ item_text = TextAreaField('Text')
+ mod_create = DateTimeField('Item Created')
+ mod_update = DateTimeField('Item Updated')
+ owner_id = SelectField('Item Owner', choices=[], coerce=int)
+ users_id = SelectMultipleField('Editors', choices=[], coerce=int)
+ submit = SubmitField('Update Item')
def __init__(self, item, *args, **kwargs):
super(EditItemForm, self).__init__(*args, **kwargs)
+ self.item_status.choices = [
+ (current_app.config['ITEM_STATUS_DRAFT'], current_app.config['ITEM_STATUS'][current_app.config['ITEM_STATUS_DRAFT']]),
+ (current_app.config['ITEM_STATUS_COMPLETED'], current_app.config['ITEM_STATUS'][current_app.config['ITEM_STATUS_COMPLETED']]),
+ (current_app.config['ITEM_STATUS_APPROVED'],current_app.config['ITEM_STATUS'][current_app.config['ITEM_STATUS_APPROVED']]),
+ (current_app.config['ITEM_STATUS_HIDDEN'], current_app.config['ITEM_STATUS'][current_app.config['ITEM_STATUS_HIDDEN']]),
+ ]
self.item = item
- Replace
active
boolean column withitem_status
integer column.
class ItemModel(db.Model):
__tablename__ = 'item'
- id = db.Column(db.BigInteger, autoincrement=True, primary_key=True)
- active = db.Column(db.Boolean, nullable=False, index=True, default=1)
- keyname = db.Column(db.String(63), nullable=False, index=True, unique=True, default='')
- item_title = db.Column(db.String(255))
- item_text = db.Column(db.Text)
- mod_create = db.Column(db.DateTime, default=datetime.utcnow)
- mod_update = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, index=True)
+ id = db.Column(db.BigInteger, autoincrement=True, primary_key=True)
+ item_status = db.Column(db.SmallInteger, nullable=False, index=True, default=1)
+ keyname = db.Column(db.String(63), nullable=False, index=True, unique=True, default='')
+ item_title = db.Column(db.String(255))
+ item_text = db.Column(db.Text)
+ mod_create = db.Column(db.DateTime, default=datetime.utcnow)
+ mod_update = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, index=True)
...
def to_json(self):
json_item = {
'url': url_for('api.get_item', id=self.id, _external=True),
- 'id' : self.id,
- 'active' : self.active,
- 'keyname' : self.keyname,
- 'item_title': self.item_title,
- 'item_text' : self.item_text,
- 'mod_create': self.mod_create,
- 'mod_update': self.mod_update,
- 'url_owner' : url_for('api.get_item_owner', id=self.id, _external=True),
- 'owner_id' : self.owner_id,
- 'url_editor': url_for('api.get_item_editor', id=self.id, _external=True),
- 'editor_id' : [iu.user_id for iu in self.item_users]
+ 'id' : self.id,
+ 'keyname' : self.keyname,
+ 'item_status': self.item_status,
+ 'item_title' : self.item_title,
+ 'item_text' : self.item_text,
+ 'mod_create' : self.mod_create,
+ 'mod_update' : self.mod_update,
+ 'url_owner' : url_for('api.get_item_owner', id=self.id, _external=True),
+ 'owner_id' : self.owner_id,
+ 'url_editor' : url_for('api.get_item_editor', id=self.id, _external=True),
+ 'editor_id' : [iu.user_id for iu in self.item_users]
}
return json_item
def __init__(self, **kwargs):
super(ItemModel, self).__init__(**kwargs)
- self.id = kwargs.get('id', None)
- self.active = kwargs.get('active', True)
- self.keyname = kwargs.get('keyname', None)
- self.item_title = kwargs.get('item_title',None)
- self.item_text = kwargs.get('item_text', 0)
- self.mod_create = kwargs.get('mod_create',None)
- self.mod_update = kwargs.get('mod_update',None)
+ self.id = kwargs.get('id', None)
+ self.keyname = kwargs.get('keyname', None)
+ self.item_status = kwargs.get('item_status', 1)
+ self.item_title = kwargs.get('item_title', None)
+ self.item_text = kwargs.get('item_text', 0)
+ self.mod_create = kwargs.get('mod_create', None)
+ self.mod_update = kwargs.get('mod_update', None)
...
def __repr__(self):
- return '<ItemModel(id=%r,active=%r,keyname=%r,item_title=%r,item_text=%r,mod_create=%r,mod_update=%r)>' \
- % (self.id,self.active,self.keyname,self.item_title,self.item_text,self.mod_create,self.mod_update)
+ return '<ItemModel(id=%r,keyname=%r,item_status=%r,item_title=%r,item_text=%r,mod_create=%r,mod_update=%r)>' \
+ % (self.id,self.keyname,self.item_status,self.item_title,self.item_text,self.mod_create,self.mod_update)
- Update panel display according to
item.item_status
values. - Replace
active
form elements withitem_status
elements.
-<div id="item_edit_panel" class="panel {% if form.active.data %}panel-info{% else %}panel-warning{% endif %}">
+<div id="item_edit_panel" class="panel {%
+ if form.item_status.data == config['ITEM_STATUS_APPROVED'] %}panel-success{%
+ elif form.item_status.data == config['ITEM_STATUS_DRAFT'] %}panel-warning{%
+ elif form.item_status.data == config['ITEM_STATUS_HIDDEN'] %}panel-danger{%
+ else %}panel-info{%
+ endif %}">
...
<div class="form-group">
- {{ form.active.label }}
- {{ form.active(class_='form-control') }}
+ {{ form.item_status.label }}
+ {{ form.item_status(class_='form-control') }}
</div>
- Replace
All
|Active
|Inactive
links withAll
|Draft
|Completed
|Approved
|Hidden
dropdown menu. - Translate
item_status
integer to proper display values. - Replace
active
|inactive
actions withapproved
|completed
|draft
|hidden
.
<tr>
<td>
- [ <a href="{{ url_for('.item_create') }}">Create Item</a> ]
+ <a href="{{ url_for('.item_create') }}" class="btn btn-default btn-sm" role="button">New Item...</a>
</td>
<td class="text-right">
- {% if session[opts_key]['status'] == 'active' %}
- [<a href="{{ url_for('.item_list') }}?status=all">All</a>]
- [Active]
- [<a href="{{ url_for('.item_list') }}?status=inactive">Inactive</a>]
- {% elif session[opts_key]['status'] == 'inactive' %}
- [<a href="{{ url_for('.item_list') }}?status=all">All</a>]
- [<a href="{{ url_for('.item_list') }}?status=active">Active</a>]
- [Inactive]
- {% else %}
- [All]
- [<a href="{{ url_for('.item_list') }}?status=active">Active</a>]
- [<a href="{{ url_for('.item_list') }}?status=inactive">Inactive</a>]
- {% endif %}
+ <div id="list-item-status" class="form-group-sm">
+ <label for="item_status" class="sr-only">Role</label>
+ <select id="item_status" name="item_status" class="form-control" onchange="window.location='{{ url_for('.item_list') }}?item_status='+this.value;">
+ <option value="-1"{% if session[opts_key]['item_status'] == -1 %} selected{% endif %}>All Items</option>
+ <option value="{{ config['ITEM_STATUS_DRAFT'] }}"{%
+ if session[opts_key]['item_status'] == config['ITEM_STATUS_DRAFT'] %} selected{% endif
+ %}>{{ config['ITEM_STATUS'][config['ITEM_STATUS_DRAFT']] }}</option>
+ <option value="{{ config['ITEM_STATUS_COMPLETED'] }}"{%
+ if session[opts_key]['item_status'] == config['ITEM_STATUS_COMPLETED'] %} selected{% endif
+ %}>{{ config['ITEM_STATUS'][config['ITEM_STATUS_COMPLETED']] }}</option>
+ <option value="{{ config['ITEM_STATUS_APPROVED'] }}"{%
+ if session[opts_key]['item_status'] == config['ITEM_STATUS_APPROVED'] %} selected{% endif
+ %}>{{ config['ITEM_STATUS'][config['ITEM_STATUS_APPROVED']] }}</option>
+ <option value="{{ config['ITEM_STATUS_HIDDEN'] }}"{%
+ if session[opts_key]['item_status'] == config['ITEM_STATUS_HIDDEN'] %} selected{% endif
+ %}>{{ config['ITEM_STATUS'][config['ITEM_STATUS_HIDDEN']] }}</option>
+ </select>
+ </div>
</td>
</tr>
</table>
...
{% for col in cols %}
<td onclick="window.location='{{ url_for('.item_view', id=row.id) }}';">
- {% if col == 'owner_id' and row.owner %}
+ {% if col == "owner_id" and row.owner %}
<a href="{{ url_for('user.user_view', id=row[col]) }}">{{ row.owner.keyname }}</a>
+ {% elif col == "item_status" %}
+ {{ config['ITEM_STATUS'][(row[col]|int)] }}
{% else %}
{{ row[col] }}
{% endif %}
...
<select id="action" name="action" class="form-control">
<option value="">Selected Items...</option>
- <option value="active">Set Active</option>
- <option value="inactive">Set Inactive</option>
+ <option value="approved">Set Status '{{ config['ITEM_STATUS'][config['ITEM_STATUS_APPROVED']] }}'</option>
+ <option value="completed">Set Status '{{ config['ITEM_STATUS'][config['ITEM_STATUS_COMPLETED']] }}'</option>
+ <option value="draft">Set Status '{{ config['ITEM_STATUS'][config['ITEM_STATUS_DRAFT']] }}'</option>
+ <option value="hidden">Set Status '{{ config['ITEM_STATUS'][config['ITEM_STATUS_HIDDEN']] }}'</option>
<option value="delete">Delete</option>
</select>
- Update panel display according to
item.item_status
values. - Translate
item_status
integer to proper display value.
-<div id="item_list_panel" class="panel {% if item.active %}panel-info{% else %}panel-warning{% endif %}">
+<div id="item_list_panel" class="panel {%
+ if item.item_status == config['ITEM_STATUS_APPROVED'] %}panel-success{%
+ elif item.item_status == config['ITEM_STATUS_DRAFT'] %}panel-warning{%
+ elif item.item_status == config['ITEM_STATUS_HIDDEN'] %}panel-danger{%
+ else %}panel-info{%
+ endif %}">
...
- <h3 class="condensed">Item '{{ item.keyname }}'{% if not item.active %} - inactive{% endif %}</h3>
+ <h3 class="condensed">Item '{{ item.keyname }}'</h3>
...
{% for col in cols %}
<tr>
<td>{{ col }}</td>
- <td>{{ item[col] }}</td>
+ <td>
+ {% if col == "item_status" %}
+ {{ config['ITEM_STATUS'][(item[col]|int)] }}
+ {% else %}
+ {{ item[col] }}
+ {% endif %}
+ </td>
</tr>
{% endfor %}
- Update
item_action()
function forapproved
,completed
,draft
andhidden
actions. - Update
rows.filter()
withinitem_list()
function to useitem_status
value.
-from flask import abort, flash, redirect, render_template, request, session, url_for
+from flask import abort, current_app, flash, redirect, render_template, request, session, url_for
...
- flash('Items Deleted (id='+id_str+')')
+ flash('Items Deleted (id='+id_str+')','success')
- if action == 'active':
+ if action in ['approved','completed','draft','hidden']:
+ new_status = current_app.config['ITEM_STATUS_APPROVED']
+ if action == 'completed':
+ new_status = current_app.config['ITEM_STATUS_COMPLETED']
+ elif action == 'draft':
+ new_status = current_app.config['ITEM_STATUS_DRAFT']
+ elif action == 'hidden':
+ new_status = current_app.config['ITEM_STATUS_HIDDEN']
for id in item_ids:
item = ItemModel.query.get_or_404(id)
- item.active = True
- db.session.add(item)
+ if item.item_status != new_status:
+ item.item_status = new_status
+ db.session.add(item)
db.session.commit()
- flash('Items Activated (id='+id_str+')')
+ flash("Items set %s (id=%s)" % (current_app.config['ITEM_STATUS'][new_status],id_str),'success')
- if action == 'inactive':
- for id in item_ids:
- item = ItemModel.query.get_or_404(id)
- item.active = False
- db.session.add(item)
- db.session.commit()
- flash('Items Deactivated (id='+id_str+')')
...
- flash('Item deleted (id=%s)' % (item.id))
+ flash('Item deleted (id=%s)' % (item.id),'success')
...
- flash('Item created (id=%s)' % (item.id))
+ flash('Item created (id=%s)' % (item.id),'success')
...
- flash('Item updated (id=%s)' % (item.id))
+ flash('Item updated (id=%s)' % (item.id),'success')
...
- if S['status'] in ['active', 'inactive']:
- rows = rows.filter(ItemModel.active == (S['status'] == 'active'))
+ if S['item_status'] >= current_app.config['ITEM_STATUS_HIDDEN']:
+ rows = rows.filter(ItemModel.item_status == S['item_status'])
- Force
user_role
form values to be integers, so they are integers everywhere.
class EditUserForm(FlaskForm):
id = HiddenField('id')
keyname = StringField('Username', validators=[InputRequired(),Length(2,63),validate_username], filters=[filter_username])
- user_role = SelectField('User Role')
+ user_role = SelectField('User Role', choices=[], coerce=int)
user_email = StringField('Email', validators=[InputRequired(),Length(1,63),Email(),validate_usermail], filters=[filter_useremail])
...
def __init__(self, user, *args, **kwargs):
super(EditUserForm, self).__init__(*args, **kwargs)
self.user_role.choices = [
- (str(current_app.config['USER_ROLE_ADMIN']),current_app.config['USER_ROLE'][current_app.config['USER_ROLE_ADMIN']]),
- (str(current_app.config['USER_ROLE_EDIT']), current_app.config['USER_ROLE'][current_app.config['USER_ROLE_EDIT']]),
- (str(current_app.config['USER_ROLE_VIEW']), current_app.config['USER_ROLE'][current_app.config['USER_ROLE_VIEW']]),
- (str(current_app.config['USER_ROLE_NONE']), current_app.config['USER_ROLE'][current_app.config['USER_ROLE_NONE']]),
+ (current_app.config['USER_ROLE_ADMIN'],current_app.config['USER_ROLE'][current_app.config['USER_ROLE_ADMIN']]),
+ (current_app.config['USER_ROLE_EDIT'], current_app.config['USER_ROLE'][current_app.config['USER_ROLE_EDIT']]),
+ (current_app.config['USER_ROLE_VIEW'], current_app.config['USER_ROLE'][current_app.config['USER_ROLE_VIEW']]),
+ (current_app.config['USER_ROLE_NONE'], current_app.config['USER_ROLE'][current_app.config['USER_ROLE_NONE']]),
]
self.user = user
-<div id="item_edit_panel" class="panel {%
- if form.user_role.data == config['USER_ROLE_ADMIN']|string %}panel-success{%
- elif form.user_role.data == config['USER_ROLE_NONE']|string %}panel-danger{%
+<div id="user_edit_panel" class="panel {%
+ if form.user_role.data == config['USER_ROLE_ADMIN'] %}panel-success{%
+ elif form.user_role.data == config['USER_ROLE_NONE'] %}panel-danger{%
else %}panel-info{%
endif %}">
- Update
action
menu foradmin
,edit
,view
andnone
actions.
-<div id="item_list_panel" class="panel panel-info">
+<div id="user_list_panel" class="panel panel-info">
...
<select id="action" name="action" class="form-control">
<option value="">Selected Users...</option>
- <option value="active">Set Active</option>
- <option value="inactive">Set Inactive</option>
+ <option value="admin">Set Role '{{ config['USER_ROLE'][config['USER_ROLE_ADMIN']] }}'</option>
+ <option value="edit">Set Role '{{ config['USER_ROLE'][config['USER_ROLE_EDIT']] }}'</option>
+ <option value="view">Set Role '{{ config['USER_ROLE'][config['USER_ROLE_VIEW']] }}'</option>
+ <option value="none">Set Role '{{ config['USER_ROLE'][config['USER_ROLE_NONE']] }}'</option>
<option value="delete">Delete</option>
</select>
-<div id="item_list_panel" class="panel {%
+<div id="user_list_panel" class="panel {%
- Update
user_action()
foradmin
,edit
,view
andnone
actions.
- flash('Invalid username or password','warning')
+ flash('Invalid username or password','danger')
...
- flash('You have been logged out.')
+ flash('You have been logged out.','success')
...
- flash('Users Deleted (id='+id_str+')')
+ flash('Users Deleted (id='+id_str+')','success')
- if action == 'active':
+ if action in ['admin','edit','view','none']:
+ new_role = current_app.config['USER_ROLE_ADMIN']
+ if action == 'edit':
+ new_role = current_app.config['USER_ROLE_EDIT']
+ elif action == 'view':
+ new_role = current_app.config['USER_ROLE_VIEW']
+ elif action == 'none':
+ new_role = current_app.config['USER_ROLE_NONE']
for id in user_ids:
user = UserModel.query.get_or_404(id)
- if user.user_role == current_app.config['USER_ROLE_NONE']:
- user.user_role = current_app.config['USER_ROLE_VIEW']
+ if user.user_role != new_role:
+ user.user_role = new_role
db.session.add(user)
db.session.commit()
- flash('Users Activated (id='+id_str+')')
+ flash("Users set %s (id=%s)" % (current_app.config['USER_ROLE'][new_role],id_str),'success')
- if action == 'inactive':
- for id in user_ids:
- user = UserModel.query.get_or_404(id)
- user.user_role = current_app.config['USER_ROLE_NONE']
- db.session.add(user)
- db.session.commit()
- flash('Users Deactivated (id='+id_str+')')
...
- flash('User deleted (id=%s)' % (user.id))
+ flash('User deleted (id=%s)' % (user.id),'success')
...
- flash('User created (id=%s)' % (user.id))
+ flash('User created (id=%s)' % (user.id),'success')
...
- flash('User updated (id=%s)' % (user.id))
+ flash('User updated (id=%s)' % (user.id),'success')
- Create constants for
item_status
values and display strings.
+ # item.item_status
+ ITEM_STATUS_HIDDEN = 0
+ ITEM_STATUS_DRAFT = 1
+ ITEM_STATUS_COMPLETED = 2
+ ITEM_STATUS_APPROVED = 3
+ ITEM_STATUS = {
+ ITEM_STATUS_HIDDEN: 'Hidden',
+ ITEM_STATUS_DRAFT: 'Draft',
+ ITEM_STATUS_COMPLETED: 'Completed',
+ ITEM_STATUS_APPROVED: 'Approved',
+ }
Commit-v0.32 | Commit-v0.33 | Commit-v0.34
- FlaskApp Tutorial
- Table of Contents
- About
- Application Setup
- Modules, Templates, and Layouts
- Database Items, Forms, and CRUD
- List Filter, Sort, and Paginate
- Users and Login
- Database Relationships
- API Module, HTTPAuth and JSON
- Refactoring User Roles and Item Status
- AJAX and Public Pages