Skip to content

Commit

Permalink
fixed #165 - action_links now support urls with multiple parameters (#…
Browse files Browse the repository at this point in the history
…212)

* fixed #165
action_links now support urls with multiple parameters

* fixed test

* fixed tests part deux

* updated changelog
  • Loading branch information
mmarcos committed Jun 13, 2017
1 parent f7904c3 commit 114a6b1
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 53 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
Always reference the ticket number at the end of the issue description.


##0.9.7 (2017-06-13)

###Fixed

- Action Links now support named urls with parameters - [#165][165]

[165]: //github.com/sanoma/django-arctic/issues/165


##0.9.6 (2017-04-25)

###Changed
Expand Down
37 changes: 24 additions & 13 deletions arctic/generics.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ class ListView(View, base.ListView):
tool_links = [] # Global links. For Example "Add object"
prefix = '' # Prefix for embedding multiple list views in detail view
max_embeded_list_items = 10 # when displaying a list in a column
primary_key = 'pk'

def get(self, request, *args, **kwargs):
objects = self.get_object_list()
Expand Down Expand Up @@ -370,7 +371,7 @@ def _reverse_field_link(self, url, obj):
args.append(find_attribute(obj, arg))
else:
named_url = url
args = [get_attribute(obj, 'pk')]
args = [get_attribute(obj, self.primary_key)]

# Instead of giving NoReverseMatch exception
# its more desirable, for field_links in listviews
Expand Down Expand Up @@ -433,6 +434,7 @@ def get_list_header(self):
return result

def get_list_items(self, objects):
self.has_action_links = False
items = []
if not self.get_fields():
for obj in objects:
Expand All @@ -444,20 +446,15 @@ def get_list_items(self, objects):
fields = []
field_links = self.get_field_links()
field_classes = self.get_field_classes()
field_actions = self.get_action_links()
for field in self.get_fields():
fields.append(field[0] if type(field) in (list, tuple)
else field)
for obj in objects:
row = []
# get the row's foreign key
row_id = getattr(obj, 'pk', None)
if row_id:
row.append(row_id)
else:
# while annotating, it's possible that there is no pk
row.append('')

for field_name in fields:
field = {'field': field_name}
field = {'type': 'field', 'field': field_name}
base_field_name = field_name.split('__')[0]
field_class = get_field_class(objects, base_field_name)
field['value'] = self.get_field_value(field_name, obj)
Expand All @@ -478,7 +475,18 @@ def get_list_items(self, objects):
if field_name in field_classes:
field['class'] = field_classes[field_name]
row.append(field)
if field_actions:
actions = []
for field_action in field_actions:
actions.append({'label': field_action['label'],
'icon': field_action['icon'],
'url': self._reverse_field_link(
field_action['url'], obj)})
row.append({'type': 'actions', 'actions': actions})
self.has_action_links = True
items.append(row)

print(items)
return items

def get_field_value(self, field_name, obj):
Expand All @@ -504,17 +512,19 @@ def get_action_links(self):
else:
allowed_action_links = []
for link in self.action_links:

url = named_url = link[1]
if type(url) in (list, tuple):
named_url = url[0]
# check permission based on named_url
if not view_from_url(link[1]).\
if not view_from_url(named_url).\
has_permission(self.request.user):
continue

icon = None
if len(link) == 3: # if an icon class is given
icon = link[2]
allowed_action_links.append({'label': link[0],
'url': link[1],
'url': url,
'icon': icon})
return allowed_action_links

Expand Down Expand Up @@ -604,8 +614,9 @@ def get_context_data(self, **kwargs):
context['prefix'] = self.prefix
context['list_header'] = self.get_list_header()
context['list_items'] = self.get_list_items(context['object_list'])
context['action_links'] = self.get_action_links()
context['tool_links'] = self.get_tool_links()
# self.has_action_links is set in get_list_items
context['has_action_links'] = self.has_action_links
context['tool_links_icon'] = self.get_tool_links_icon()
if self.get_filter_fields() or self.get_search_fields():
context['has_filter'] = True
Expand Down
62 changes: 31 additions & 31 deletions arctic/templates/arctic/partials/base_data_table.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,46 +60,46 @@
</th>
{% endfor %}

{% if action_links %}
{% if has_action_links %}
<th class="highlight-background">{% trans "Actions" %}</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for row in list_items %}
<tr>
{% for column in row|slice:"1:" %}
<td {% if column.class %}class="{{ column.class }}"{%endif%}>
{% if column.url %}
<a href="{{ column.url }}">
{% endif %}
{% if column.value|typename != 'list' %}
{{ column.value|default_if_none:"" }}
{% else %}
{% for item in column.value %}
<span class="badge highlight-background">{{ item }}</span>
{% for column in row %}
{% if column.type == 'field' %}
<td {% if column.class %}class="{{ column.class }}"{%endif%}>
{% if column.url %}
<a href="{{ column.url }}">
{% endif %}
{% if column.value|typename != 'list' %}
{{ column.value|default_if_none:"" }}
{% else %}
{% for item in column.value %}
<span class="badge highlight-background">{{ item }}</span>
{% endfor %}
{% endif %}
{% if column.url %}
</a>
{% endif %}
</td>
{% elif column.type == 'actions' %}
<td class="actions">
{% for link in column.actions %}
<a href="{{ link.url }}" class="action-{{ link.label }}" title="{{ link.label|capfirst }}">
{% if link.icon %}
<i class="fa {{ link.icon }} fa-lg"></i>
{% else %}
{{ link.label|capfirst }}
{% endif %}
</a>
&nbsp;
{% endfor %}
{% endif %}
{% if column.url %}
</a>
{% endif %}
</td>
</td>
{% endif %}
{% endfor %}

{% if action_links %}
<td class="actions">
{% for link in action_links %}
<a href="{% url link.url row.0 %}" class="action-{{ link.label }}" title="{{ link.label|capfirst }}">
{% if link.icon %}
<i class="fa {{ link.icon }} fa-lg"></i>
{% else %}
{{ link.label|capfirst }}
{% endif %}
</a>
&nbsp;
{% endfor %}
</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
Expand Down
4 changes: 3 additions & 1 deletion tests/test_generics/test_list_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ def test_single_item(self, admin_client):
article = ArticleFactory()
response = self._request(admin_client)
self._assert_list_items_len(response, 1)
assert response.context_data['list_items'][0][0] == article.pk
field = response.context_data['list_items'][0][0]['field']
assert response.context_data['list_items'][0][0]['value'] == \
getattr(article, field)

def test_paginated_items(self, admin_client):
"""
Expand Down
13 changes: 5 additions & 8 deletions tests/test_virtual_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ def test_virtual_field(self, admin_client):
self._assert_list_items_len(response, 1)

item = response.context_data['list_items'][0]
assert item[1]['value'] == article.title
assert item[2]['value'] == article.description
assert item[3]['value'] == article.published
assert item[4]['value'] == article.category.name
assert item[0]['value'] == article.title
assert item[1]['value'] == article.description
assert item[2]['value'] == article.published
assert item[3]['value'] == article.category.name

def test_missing_virtual_field(self, admin_client):
"""
Expand All @@ -44,10 +44,7 @@ def test_missing_virtual_field(self, admin_client):

search_virtual_field = False
for field in response.context_data['list_items'][0]:
if type(field) == int:
continue

if 'virtual_field' in field['field']:
if field['type'] == 'field' and 'virtual_field' in field['field']:
search_virtual_field = True

assert search_virtual_field is False

0 comments on commit 114a6b1

Please sign in to comment.