Skip to content
Snippets Groups Projects
Commit 31072e8d authored by Alice Heaton's avatar Alice Heaton :speech_balloon:
Browse files

Make the form work for adding items too. This doesn't implement the actual save action.

parent e138887e
No related branches found
No related tags found
1 merge request!40Add item frontend
......@@ -86,13 +86,19 @@
</div>
</div></div>
<div class="col-xs-12">
<div class="form-group btn-group pull-right">
{% bootstrap_button "Update" button_type="submit" name="action" value="update" button_class="pull-right btn btn-sm btn-success" %}
{% bootstrap_button "Cancel" button_type="submit" name="action" value="cancel" button_class="pull-left btn btn-sm" %}
</div>
<div class="form-group btn-group pull-left">
{% bootstrap_button "Delete" button_type="submit" name="action" value="delete" button_class="btn btn-danger btn-sm" %}
</div>
{% if update %}
<div class="form-group btn-group pull-right">
{% bootstrap_button "Update" button_type="submit" name="action" value="update" button_class="pull-right btn btn-sm btn-success" %}
{% bootstrap_button "Cancel" button_type="submit" name="action" value="cancel" button_class="pull-left btn btn-sm" %}
</div>
<div class="form-group btn-group pull-left">
{% bootstrap_button "Delete" button_type="submit" name="action" value="delete" button_class="btn btn-danger btn-sm" %}
</div>
{% else %}
<div class="form-group btn-group pull-right">
{% bootstrap_button "Create" button_type="submit" name="action" value="create" button_class="pull-right btn btn-sm btn-success" %}
</div>
{% endif %}
</div>
</div></div>
</form>
......
......@@ -95,6 +95,15 @@ def generic_item():
}
@pytest.fixture
def an_item_type():
return {
'taxonomy': 'item-types',
'name': 'an-item-type',
'long_name': 'An Item Type'
}
def test_the_item_is_added_to_the_view_on_get_requests(generic_item):
with patch('hid.views.item.transport.items.get') as get_item:
get_item.return_value = generic_item
......@@ -308,3 +317,56 @@ def test_displaying_unknown_item_returns_redirect_response(generic_item):
)
assert type(response) is HttpResponseRedirect
def test_add_new_item_get_request_populates_item_type(an_item_type):
with patch('hid.views.item.transport.terms.list') as list_term:
list_term.return_value = [an_item_type]
(view, response) = make_request(
AddEditItemView,
'add-item',
kwargs={'item_type': 'an-item-type'},
)
assert view.item_type == an_item_type
def test_add_new_item_post_request_populates_item_type(an_item_type):
with patch('hid.views.item.transport.terms.list') as list_term:
list_term.return_value = [an_item_type]
(view, response) = make_request(
AddEditItemView,
'add-item',
kwargs={'item_type': 'an-item-type'},
request_type='post',
post={
'action': 'save',
'next': ''
}
)
assert view.item_type == an_item_type
def test_add_new_item_returns_template_response(an_item_type):
with patch('hid.views.item.transport.terms.list') as list_term:
list_term.return_value = [an_item_type]
(view, response) = make_request(
AddEditItemView,
'add-item',
kwargs={'item_type': 'an-item-type'},
)
assert type(response) is TemplateResponse
def test_add_new_item_with_unknown_item_type_redirects():
with patch('hid.views.item.transport.terms.list') as list_term:
list_term.return_value = []
(view, response) = make_request(
AddEditItemView,
'add-item',
kwargs={'item_type': 'an-item-type'},
)
assert type(response) is HttpResponseRedirect
......@@ -15,5 +15,6 @@ urlpatterns = patterns('',
url(r'^sources/$', login_required(ListSources.as_view()), name='sources'),
url(r'^process-items/$', login_required(view_and_edit_table_form_process_items), name="data-view-process"),
url(r'^item/(?P<item_id>\d+)/edit/$', login_required(AddEditItemView.as_view()), name='edit-item'),
url(r'^item/add/(?P<item_type>[-_\w]+)/$', login_required(AddEditItemView.as_view()), name='add-item'),
url(r'^$', login_required(DashboardView.as_view()), name='dashboard'),
)
from datetime import datetime
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext as _
......@@ -8,35 +10,64 @@ from ..forms.item import AddEditItemForm
from ..constants import ITEM_TYPE_CATEGORY
class ItemTypeNotFound(Exception):
""" Exception raised internally when an item type is not found """
pass
class ItemNotFound(Exception):
""" Exception raised internally when an item is not found """
pass
class AddEditItemView(FormView):
template_name = "hid/add_edit_item.html"
form_class = AddEditItemForm
def _initialize_item(self, item_id):
""" Initialize the view's item from the given item id.
def _initialize_item(self, item_id, item_type):
""" Initialize the view's item from the given item id or item_type
This has a side effect of initializing:
self.item_type to the item type (either from the given type
of from the given item)
self.item to the item object (or None)
self.item_type to the item type, if defined (None otherwise)
self.item_terms to a dictionary of taxonomy to list of terms
(or {})
Args:
item_id (int): Item id
item_id (int): Item id to initialize from
item_type (str): Item type to initialize item_type from.
This is used only if item_id is None.
Raises:
ItemNotFound: If the item was not found
ItemTypeNotFound: If the item type was not found
"""
self.item = None
self.item_type = None
self.item_terms = None
if not item_id:
return
self.item = transport.items.get(item_id)
self.item_terms = {}
for term in self.item['terms']:
taxonomy = term['taxonomy']
if taxonomy == 'item-types':
self.item_type = term
if taxonomy not in self.item_terms:
self.item_terms[taxonomy] = []
self.item_terms[taxonomy].append(term)
if item_id:
try:
self.item = transport.items.get(item_id)
except transport.exceptions.TransportException:
raise ItemNotFound()
self.item_terms = {}
for term in self.item['terms']:
taxonomy = term['taxonomy']
if taxonomy == 'item-types':
self.item_type = term
if taxonomy not in self.item_terms:
self.item_terms[taxonomy] = []
self.item_terms[taxonomy].append(term)
elif item_type:
matches = transport.terms.list(
taxonomy='item-types',
name=item_type
)
if len(matches) == 0:
raise ItemTypeNotFound()
else:
self.item_type = matches[0]
def get(self, request, *args, **kwargs):
""" get request handler
......@@ -45,14 +76,23 @@ class AddEditItemView(FormView):
to make it available for forms.
"""
try:
self._initialize_item(kwargs.get('item_id'))
except transport.exceptions.TransportException:
self._initialize_item(
kwargs.get('item_id'), kwargs.get('item_type')
)
except ItemNotFound:
return self._response(
self.request.GET.get('next', '/'),
messages.ERROR,
(_('Item with id %s could not be found') %
str(kwargs.get('item_id')))
)
except ItemTypeNotFound:
return self._response(
self.request.GET.get('next', '/'),
messages.ERROR,
(_('Item type %s could not be found') %
str(kwargs.get('item_type')))
)
return super(AddEditItemView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
......@@ -65,14 +105,23 @@ class AddEditItemView(FormView):
valid for those.
"""
try:
self._initialize_item(kwargs.get('item_id'))
except transport.exceptions.TransportException:
self._initialize_item(
kwargs.get('item_id'), kwargs.get('item_type')
)
except ItemNotFound:
return self._response(
self.request.GET.get('next', '/'),
messages.ERROR,
(_('Item with id %s could not be found') %
str(kwargs.get('item_id')))
)
except ItemTypeNotFound:
return self._response(
self.request.GET.get('next', '/'),
messages.ERROR,
(_('Item type %s could not be found') %
str(kwargs.get('item_type')))
)
if 'cancel' in self.request.POST['action']:
return self._response(
......@@ -92,15 +141,18 @@ class AddEditItemView(FormView):
def get_initial(self):
""" Return the form object's initial values for the current item """
if self.item is None:
return {
'id': 0
initial = {
'id': 0,
'timestamp': datetime.now(),
'next': self.request.GET.get('next', self.request.path)
}
else:
initial = {
'id': self.item['id'],
'body': self.item['body'],
'timestamp': self.item['timestamp'],
'next': self.request.GET.get('next', self.request.path)
}
initial = {
'id': self.item['id'],
'body': self.item['body'],
'timestamp': self.item['timestamp'],
'next': self.request.GET.get('next', self.request.path)
}
taxonomy = ITEM_TYPE_CATEGORY.get(self.item_type['name'])
if (taxonomy and taxonomy in self.item_terms
and len(self.item_terms[taxonomy]) > 0):
......@@ -110,13 +162,7 @@ class AddEditItemView(FormView):
def get_form(self, form_class):
""" Return the form object to be used """
if self.item_type:
item_type = self.item_type['name']
else:
# TODO: When implementing ADD mode, we'll need to use the URL to
# get the default
item_type = None
return form_class(item_type, **self.get_form_kwargs())
return form_class(self.item_type['name'], **self.get_form_kwargs())
def get_context_data(self, **kwargs):
""" Get the form's context data
......@@ -126,15 +172,12 @@ class AddEditItemView(FormView):
"""
context = super(AddEditItemView, self).get_context_data(**kwargs)
# Add item to the context
# Add item and form mode to the context
context['item'] = self.item
context['update'] = self.item is not None
# Add the type label to the context
# TODO: When implementing ADD mode, we'll need to use the URL to
# get the default.
context['item_type_label'] = '?'
if self.item_type:
context['item_type_label'] = self.item_type['long_name']
context['item_type_label'] = self.item_type['long_name']
# Add the width of the option row to the context
option_row_widget_count = 1 # We always have 'created'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment