Support marking columns as indetifier and sortable
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -124,6 +124,8 @@
|
|||||||
* Add document state action view test.
|
* Add document state action view test.
|
||||||
* Remove sidebar menu instance. The secondary menu and the
|
* Remove sidebar menu instance. The secondary menu and the
|
||||||
previour sidebar menu now perform the same function.
|
previour sidebar menu now perform the same function.
|
||||||
|
* Backport source column identifiable and sortable
|
||||||
|
improvements.
|
||||||
|
|
||||||
3.1.11 (2019-04-XX)
|
3.1.11 (2019-04-XX)
|
||||||
===================
|
===================
|
||||||
|
|||||||
@@ -156,6 +156,9 @@ Other changes
|
|||||||
* Add document state action view test.
|
* Add document state action view test.
|
||||||
* Remove sidebar menu instance. The secondary menu and the
|
* Remove sidebar menu instance. The secondary menu and the
|
||||||
previour sidebar menu now perform the same function.
|
previour sidebar menu now perform the same function.
|
||||||
|
* Backport source column identifiable and sortable
|
||||||
|
improvements.
|
||||||
|
|
||||||
|
|
||||||
Removals
|
Removals
|
||||||
--------
|
--------
|
||||||
|
|||||||
@@ -50,24 +50,25 @@
|
|||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label for="id_indexes_0">
|
<label for="id_indexes_0">
|
||||||
{% if multi_item_actions %}
|
{% if multi_item_actions %}
|
||||||
{% if multi_select_item_properties %}
|
<input class="form-multi-object-action-checkbox check-all-slave checkbox" type="checkbox" name="pk_{{ object.pk }}" />
|
||||||
<input class="form-multi-object-action-checkbox check-all-slave checkbox" type="checkbox" name="properties_{{ object|get_encoded_parameter:multi_select_item_properties }}" />
|
|
||||||
{% else %}
|
|
||||||
<input class="form-multi-object-action-checkbox check-all-slave checkbox" type="checkbox" name="pk_{{ object.pk }}" />
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<span style="color: white; word-break: break-all; overflow-wrap: break-word;">
|
<span style="color: white; word-break: break-all; overflow-wrap: break-word;">
|
||||||
{% if not hide_object %}
|
{% if not hide_object %}
|
||||||
{% if main_object %}
|
{% if not hide_link %}
|
||||||
{% with object|object_property:main_object as object %}
|
<a href="{{ object.get_absolute_url }}">{{ object }}</a>
|
||||||
{% if not hide_link %}<a href="{{ object.get_absolute_url }}">{{ object }}</a>{% else %}{{ object }}{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if not hide_link %}<a href="{{ object.get_absolute_url }}">{{ object }}</a>{% else %}{{ object }}{% endif %}
|
{{ object }}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% navigation_get_source_columns source=object only_identifier=True as source_column %}
|
||||||
|
{% navigation_source_column_resolve column=source_column as column_value %}
|
||||||
|
{% if source_column.is_absolute_url %}
|
||||||
|
<a href="{{ column_value.get_absolute_url|default:object.get_absolute_url }}">{{ column_value }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ column_value }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -77,8 +78,9 @@
|
|||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
|
|
||||||
{% if not hide_columns %}
|
{% if not hide_columns %}
|
||||||
{% for column in object|get_source_columns %}
|
{% navigation_get_source_columns source=object exclude_identifier=True as source_columns %}
|
||||||
<div class="text-center" style="">{% source_column_resolve column=column %}{{ column_result }}</div>
|
{% for column in source_columns %}
|
||||||
|
<div class="text-center" style="">{% navigation_source_column_resolve column=column as column_value %}{% if column_value != '' %}{% if column.include_label %}{{ column.label }}: {% endif %}{{ column_value }}{% endif %}</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table class="table table-condensed table-striped">
|
<table class="table table-condensed table-striped table-hover">
|
||||||
<tbody>
|
<tbody>
|
||||||
{% if not hide_header %}
|
{% if not hide_header %}
|
||||||
<tr>
|
<tr>
|
||||||
@@ -48,11 +48,37 @@
|
|||||||
|
|
||||||
{% if not hide_object %}
|
{% if not hide_object %}
|
||||||
<th>{% trans 'Identifier' %}</th>
|
<th>{% trans 'Identifier' %}</th>
|
||||||
|
{% else %}
|
||||||
|
{% navigation_get_source_columns source=object_list only_identifier=True as source_column %}
|
||||||
|
{% if source_column %}
|
||||||
|
<th>
|
||||||
|
{% if source_column.is_sortable %}
|
||||||
|
<a href="{% navigation_get_sort_field_querystring column=source_column %}">{{ source_column.label }}
|
||||||
|
{% if navigation_source_column.get_sort_field == sort_field %}
|
||||||
|
{% if icon_sort %}{{ icon_sort.render }}{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
{{ source_column.label }}
|
||||||
|
{% endif %}
|
||||||
|
</th>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if not hide_columns %}
|
{% if not hide_columns %}
|
||||||
{% for column in object_list|get_source_columns %}
|
{% navigation_get_source_columns source=object_list exclude_identifier=True as source_columns %}
|
||||||
<th>{{ column.label }}</th>
|
{% for column in source_columns %}
|
||||||
|
<th>
|
||||||
|
{% if column.is_sortable %}
|
||||||
|
<a href="{% navigation_get_sort_field_querystring column=column %}">{{ column.label }}
|
||||||
|
{% if column.get_sort_field == sort_field %}
|
||||||
|
{% if icon_sort %}{{ icon_sort.render }}{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
{{ column.label }}
|
||||||
|
{% endif %}
|
||||||
|
</th>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@@ -68,60 +94,68 @@
|
|||||||
{% for object in object_list %}
|
{% for object in object_list %}
|
||||||
<tr>
|
<tr>
|
||||||
|
|
||||||
{% if multi_item_actions %}
|
{% if multi_item_actions %}
|
||||||
<td>
|
<td>
|
||||||
{% if multi_select_item_properties %}
|
<input type="checkbox" class="form-multi-object-action-checkbox check-all-slave checkbox" name="pk_{{ object.pk }}" value="" />
|
||||||
<input type="checkbox" class="form-multi-object-action-checkbox check-all-slave checkbox" name="properties_{{ object|get_encoded_parameter:multi_select_item_properties }}" value="" />
|
</td>
|
||||||
{% else %}
|
|
||||||
<input type="checkbox" class="form-multi-object-action-checkbox check-all-slave checkbox" name="pk_{{ object.pk }}" value="" />
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
|
||||||
{% endif %}
|
{% if not hide_object %}
|
||||||
{% if not hide_object %}
|
|
||||||
{% if main_object %}
|
|
||||||
{% with object|object_property:main_object as object %}
|
|
||||||
<td>{% if not hide_link %}<a href="{{ object.get_absolute_url }}">{{ object }}</a>{% else %}{{ object }}{% endif %}</td>
|
|
||||||
{% endwith %}
|
|
||||||
{% else %}
|
|
||||||
<td>{% if not hide_link %}<a href="{{ object.get_absolute_url }}">{{ object }}</a>{% else %}{{ object }}{% endif %}</td>
|
<td>{% if not hide_link %}<a href="{{ object.get_absolute_url }}">{{ object }}</a>{% else %}{{ object }}{% endif %}</td>
|
||||||
|
{% else %}
|
||||||
|
{% navigation_get_source_columns source=object only_identifier=True as source_column %}
|
||||||
|
{% navigation_source_column_resolve column=source_column as column_value %}
|
||||||
|
{% if column_value %}
|
||||||
|
<td>
|
||||||
|
{% if source_column.is_absolute_url %}
|
||||||
|
<a href="{{ column_value.get_absolute_url|default:object.get_absolute_url }}">{{ column_value }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ column_value }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
{% if not hide_columns %}
|
{% if not hide_columns %}
|
||||||
{% for column in object|get_source_columns %}
|
{% navigation_get_source_columns source=object exclude_identifier=True as source_columns %}
|
||||||
<td>{% source_column_resolve column=column %}{{ column_result }}</td>
|
{% for column in source_columns %}
|
||||||
{% endfor %}
|
<td>
|
||||||
{% endif %}
|
<div class="{{ table_cell_container_classes }}">
|
||||||
{% for column in extra_columns %}
|
{% navigation_source_column_resolve column=column as column_value %}{{ column_value }}
|
||||||
<td>{{ object|object_property:column.attribute }}</td>
|
{# Use explicit 'as column_value ' to force date rendering #}
|
||||||
{% endfor %}
|
</div>
|
||||||
{% if not hide_links %}
|
</td>
|
||||||
<td class="last">
|
|
||||||
{% navigation_resolve_menu name='list facet' sort_results=True source=object as facet_menus_results %}
|
|
||||||
{% for facet_menu_results in facet_menus_results %}
|
|
||||||
{% for link_group in facet_menu_results.link_groups %}
|
|
||||||
{% with link_group.links as object_navigation_links %}
|
|
||||||
{% with 'true' as horizontal %}
|
|
||||||
{% with 'true' as hide_icon %}
|
|
||||||
{% include 'navigation/generic_navigation.html' %}
|
|
||||||
{% endwith %}
|
|
||||||
{% endwith %}
|
|
||||||
{% endwith %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% navigation_resolve_menu name='object' source=object as object_menus_results %}
|
{% endif %}
|
||||||
{% for object_menu_results in object_menus_results %}
|
|
||||||
{% for link_group in object_menu_results.link_groups %}
|
{% if not hide_links %}
|
||||||
{% with link_group.links as object_navigation_links %}
|
<td class="last">
|
||||||
{% with 'true' as horizontal %}
|
{% navigation_resolve_menu name='list facet' sort_results=True source=object as facet_menus_results %}
|
||||||
{% with 'true' as hide_icon %}
|
{% for facet_menu_results in facet_menus_results %}
|
||||||
{% include 'navigation/generic_navigation.html' %}
|
{% for link_group in facet_menu_results.link_groups %}
|
||||||
{% endwith %}
|
{% with link_group.links as object_navigation_links %}
|
||||||
{% endwith %}
|
{% with 'true' as horizontal %}
|
||||||
{% endwith %}
|
{% with 'true' as hide_icon %}
|
||||||
|
{% include 'navigation/generic_navigation.html' %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% navigation_resolve_menu name='object' source=object as object_menus_results %}
|
||||||
</td>
|
{% for object_menu_results in object_menus_results %}
|
||||||
{% endif %}
|
{% for link_group in object_menu_results.link_groups %}
|
||||||
|
{% with link_group.links as object_navigation_links %}
|
||||||
|
{% with 'true' as horizontal %}
|
||||||
|
{% with 'true' as hide_icon %}
|
||||||
|
{% include 'navigation/generic_navigation.html' %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -22,7 +22,15 @@ from django_downloadview import (
|
|||||||
from pure_pagination.mixins import PaginationMixin
|
from pure_pagination.mixins import PaginationMixin
|
||||||
|
|
||||||
from .forms import ChoiceForm
|
from .forms import ChoiceForm
|
||||||
from .icons import icon_assign_remove_add, icon_assign_remove_remove
|
from .icons import (
|
||||||
|
icon_assign_remove_add, icon_assign_remove_remove, icon_sort_down,
|
||||||
|
icon_sort_up
|
||||||
|
)
|
||||||
|
from .literals import (
|
||||||
|
TEXT_SORT_FIELD_PARAMETER, TEXT_SORT_FIELD_VARIABLE_NAME,
|
||||||
|
TEXT_SORT_ORDER_CHOICE_ASCENDING, TEXT_SORT_ORDER_PARAMETER,
|
||||||
|
TEXT_SORT_ORDER_VARIABLE_NAME
|
||||||
|
)
|
||||||
from .mixins import (
|
from .mixins import (
|
||||||
DeleteExtraDataMixin, DynamicFormViewMixin, ExtraContextMixin,
|
DeleteExtraDataMixin, DynamicFormViewMixin, ExtraContextMixin,
|
||||||
FormExtraKwargsMixin, MultipleObjectMixin, ObjectActionMixin,
|
FormExtraKwargsMixin, MultipleObjectMixin, ObjectActionMixin,
|
||||||
@@ -495,12 +503,52 @@ class SingleObjectListView(PaginationMixin, ViewPermissionCheckMixin, ObjectList
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(SingleObjectListView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
context.update(
|
||||||
|
{
|
||||||
|
TEXT_SORT_FIELD_VARIABLE_NAME: self.get_sort_field(),
|
||||||
|
TEXT_SORT_ORDER_VARIABLE_NAME: self.get_sort_order(),
|
||||||
|
'icon_sort': self.get_sort_icon(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return context
|
||||||
|
|
||||||
def get_paginate_by(self, queryset):
|
def get_paginate_by(self, queryset):
|
||||||
return setting_paginate_by.value
|
return setting_paginate_by.value
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
try:
|
try:
|
||||||
return super(SingleObjectListView, self).get_queryset()
|
queryset = super(SingleObjectListView, self).get_queryset()
|
||||||
except ImproperlyConfigured:
|
except ImproperlyConfigured:
|
||||||
self.queryset = self.get_object_list()
|
self.queryset = self.get_object_list()
|
||||||
return super(SingleObjectListView, self).get_queryset()
|
queryset = super(SingleObjectListView, self).get_queryset()
|
||||||
|
|
||||||
|
self.field_name = self.get_sort_field()
|
||||||
|
if self.get_sort_order() == TEXT_SORT_ORDER_CHOICE_ASCENDING:
|
||||||
|
sort_order = ''
|
||||||
|
else:
|
||||||
|
sort_order = '-'
|
||||||
|
|
||||||
|
if self.field_name:
|
||||||
|
queryset = queryset.order_by(
|
||||||
|
'{}{}'.format(sort_order, self.field_name)
|
||||||
|
)
|
||||||
|
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
def get_sort_field(self):
|
||||||
|
return self.request.GET.get(TEXT_SORT_FIELD_PARAMETER)
|
||||||
|
|
||||||
|
def get_sort_icon(self):
|
||||||
|
sort_order = self.get_sort_order()
|
||||||
|
if not sort_order:
|
||||||
|
return
|
||||||
|
elif sort_order == TEXT_SORT_ORDER_CHOICE_ASCENDING:
|
||||||
|
return icon_sort_down
|
||||||
|
else:
|
||||||
|
return icon_sort_up
|
||||||
|
|
||||||
|
def get_sort_order(self):
|
||||||
|
return self.request.GET.get(TEXT_SORT_ORDER_PARAMETER)
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ icon_social_paypal = Icon(
|
|||||||
icon_social_twitter = Icon(
|
icon_social_twitter = Icon(
|
||||||
driver_name='fontawesomecss', css_classes='fab fa-twitter'
|
driver_name='fontawesomecss', css_classes='fab fa-twitter'
|
||||||
)
|
)
|
||||||
|
icon_sort_down = Icon(driver_name='fontawesome', symbol='sort-down')
|
||||||
|
icon_sort_up = Icon(driver_name='fontawesome', symbol='sort-up')
|
||||||
icon_source_code = Icon(driver_name='fontawesome', symbol='code-branch')
|
icon_source_code = Icon(driver_name='fontawesome', symbol='code-branch')
|
||||||
icon_support = Icon(
|
icon_support = Icon(
|
||||||
driver_name='fontawesome', symbol='phone'
|
driver_name='fontawesome', symbol='phone'
|
||||||
|
|||||||
@@ -11,6 +11,14 @@ MESSAGE_SQLITE_WARNING = _(
|
|||||||
'for development and testing, not for production.'
|
'for development and testing, not for production.'
|
||||||
)
|
)
|
||||||
PYPI_URL = 'https://pypi.python.org/pypi'
|
PYPI_URL = 'https://pypi.python.org/pypi'
|
||||||
|
|
||||||
|
TEXT_SORT_FIELD_PARAMETER = '_sort_field'
|
||||||
|
TEXT_SORT_FIELD_VARIABLE_NAME = 'sort_field'
|
||||||
|
TEXT_SORT_ORDER_CHOICE_ASCENDING = 'asc'
|
||||||
|
TEXT_SORT_ORDER_CHOICE_DESCENDING = 'desc'
|
||||||
|
TEXT_SORT_ORDER_PARAMETER = '_sort_order'
|
||||||
|
TEXT_SORT_ORDER_VARIABLE_NAME = 'sort_order'
|
||||||
|
|
||||||
TIME_DELTA_UNIT_DAYS = 'days'
|
TIME_DELTA_UNIT_DAYS = 'days'
|
||||||
TIME_DELTA_UNIT_HOURS = 'hours'
|
TIME_DELTA_UNIT_HOURS = 'hours'
|
||||||
TIME_DELTA_UNIT_MINUTES = 'minutes'
|
TIME_DELTA_UNIT_MINUTES = 'minutes'
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ from django.urls import resolve, reverse
|
|||||||
from django.utils.encoding import force_str, force_text
|
from django.utils.encoding import force_str, force_text
|
||||||
from django.utils.module_loading import import_string
|
from django.utils.module_loading import import_string
|
||||||
|
|
||||||
|
from mayan.apps.common.literals import (
|
||||||
|
TEXT_SORT_FIELD_PARAMETER, TEXT_SORT_FIELD_VARIABLE_NAME,
|
||||||
|
TEXT_SORT_ORDER_CHOICE_ASCENDING, TEXT_SORT_ORDER_CHOICE_DESCENDING,
|
||||||
|
TEXT_SORT_ORDER_PARAMETER, TEXT_SORT_ORDER_VARIABLE_NAME
|
||||||
|
)
|
||||||
from mayan.apps.common.settings import setting_home_view
|
from mayan.apps.common.settings import setting_home_view
|
||||||
from mayan.apps.common.utils import resolve_attribute
|
from mayan.apps.common.utils import resolve_attribute
|
||||||
from mayan.apps.permissions import Permission
|
from mayan.apps.permissions import Permission
|
||||||
@@ -528,38 +533,90 @@ class SourceColumn(object):
|
|||||||
return sorted(columns, key=lambda x: x.order)
|
return sorted(columns, key=lambda x: x.order)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_for_source(cls, source):
|
def get_for_source(cls, context, source, exclude_identifier=False, only_identifier=False):
|
||||||
try:
|
try:
|
||||||
return SourceColumn.sort(columns=cls._registry[source])
|
result = cls._registry[source]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
# Try it as a queryset
|
# Might be an instance, try its class
|
||||||
return SourceColumn.sort(columns=cls._registry[source.model])
|
result = cls._registry[source.__class__]
|
||||||
except AttributeError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
# It seems to be an instance, try its class
|
# Might be an inherited class insance, try its source class
|
||||||
return SourceColumn.sort(columns=cls._registry[source.__class__])
|
result = cls._registry[source.source_ptr.__class__]
|
||||||
except KeyError:
|
except (KeyError, AttributeError):
|
||||||
try:
|
try:
|
||||||
# Special case for queryset items produced from
|
# Try it as a queryset
|
||||||
# .defer() or .only() optimizations
|
result = cls._registry[source.model]
|
||||||
return SourceColumn.sort(columns=cls._registry[list(source._meta.parents.items())[0][0]])
|
except AttributeError:
|
||||||
except (AttributeError, KeyError, IndexError):
|
try:
|
||||||
return ()
|
# Special case for queryset items produced from
|
||||||
|
# .defer() or .only() optimizations
|
||||||
|
result = cls._registry[list(source._meta.parents.items())[0][0]]
|
||||||
|
except (AttributeError, KeyError, IndexError):
|
||||||
|
result = ()
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# unhashable type: list
|
# unhashable type: list
|
||||||
return ()
|
result = ()
|
||||||
|
|
||||||
def __init__(self, source, label=None, attribute=None, func=None, kwargs=None, order=None, widget=None):
|
result = SourceColumn.sort(columns=result)
|
||||||
|
|
||||||
|
if exclude_identifier:
|
||||||
|
result = [item for item in result if not item.is_identifier]
|
||||||
|
else:
|
||||||
|
if only_identifier:
|
||||||
|
for item in result:
|
||||||
|
if item.is_identifier:
|
||||||
|
return item
|
||||||
|
return None
|
||||||
|
|
||||||
|
final_result = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
request = context.request
|
||||||
|
except AttributeError:
|
||||||
|
# Simple request extraction failed. Might not be a view context.
|
||||||
|
# Try alternate method.
|
||||||
|
try:
|
||||||
|
request = Variable('request').resolve(context)
|
||||||
|
except VariableDoesNotExist:
|
||||||
|
# There is no request variable, most probable a 500 in a test
|
||||||
|
# view. Don't return any resolved request.
|
||||||
|
logger.warning(
|
||||||
|
'No request variable, aborting request resolution'
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
current_view_name = get_current_view_name(request=request)
|
||||||
|
for item in result:
|
||||||
|
if item.views:
|
||||||
|
if current_view_name in item.views:
|
||||||
|
final_result.append(item)
|
||||||
|
else:
|
||||||
|
final_result.append(item)
|
||||||
|
|
||||||
|
return final_result
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, source, label=None, attribute=None, func=None,
|
||||||
|
is_absolute_url=False, is_identifier=False, is_sortable=False,
|
||||||
|
kwargs=None, order=None, sort_field=None, views=None, widget=None
|
||||||
|
):
|
||||||
self.source = source
|
self.source = source
|
||||||
self._label = label
|
self._label = label
|
||||||
self.attribute = attribute
|
self.attribute = attribute
|
||||||
self.func = func
|
self.func = func
|
||||||
|
self.is_absolute_url = is_absolute_url
|
||||||
|
self.is_identifier = is_identifier
|
||||||
|
self.is_sortable = is_sortable
|
||||||
self.kwargs = kwargs or {}
|
self.kwargs = kwargs or {}
|
||||||
self.order = order or 0
|
self.order = order or 0
|
||||||
|
self.sort_field = sort_field
|
||||||
|
self.views = views or []
|
||||||
|
self.widget = widget
|
||||||
|
|
||||||
self.__class__._registry.setdefault(source, [])
|
self.__class__._registry.setdefault(source, [])
|
||||||
self.__class__._registry[source].append(self)
|
self.__class__._registry[source].append(self)
|
||||||
self.widget = widget
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def label(self):
|
def label(self):
|
||||||
@@ -574,7 +631,39 @@ class SourceColumn(object):
|
|||||||
|
|
||||||
return self._label
|
return self._label
|
||||||
|
|
||||||
|
def get_sort_field(self):
|
||||||
|
if self.sort_field:
|
||||||
|
return self.sort_field
|
||||||
|
else:
|
||||||
|
return self.attribute
|
||||||
|
|
||||||
|
def get_sort_field_querystring(self, context):
|
||||||
|
# We do this to get an mutable copy we can modify
|
||||||
|
querystring = context.request.GET.copy()
|
||||||
|
|
||||||
|
previous_sort_field = context.get(TEXT_SORT_FIELD_VARIABLE_NAME, None)
|
||||||
|
previous_sort_order = context.get(
|
||||||
|
TEXT_SORT_ORDER_VARIABLE_NAME, TEXT_SORT_ORDER_CHOICE_DESCENDING
|
||||||
|
)
|
||||||
|
|
||||||
|
if previous_sort_field != self.get_sort_field():
|
||||||
|
sort_order = TEXT_SORT_ORDER_CHOICE_ASCENDING
|
||||||
|
else:
|
||||||
|
if previous_sort_order == TEXT_SORT_ORDER_CHOICE_DESCENDING:
|
||||||
|
sort_order = TEXT_SORT_ORDER_CHOICE_ASCENDING
|
||||||
|
else:
|
||||||
|
sort_order = TEXT_SORT_ORDER_CHOICE_DESCENDING
|
||||||
|
|
||||||
|
querystring[TEXT_SORT_FIELD_PARAMETER] = self.get_sort_field()
|
||||||
|
querystring[TEXT_SORT_ORDER_PARAMETER] = sort_order
|
||||||
|
|
||||||
|
return '?{}'.format(querystring.urlencode())
|
||||||
|
|
||||||
def resolve(self, context):
|
def resolve(self, context):
|
||||||
|
if self.views:
|
||||||
|
if get_current_view_name(request=context.request) not in self.views:
|
||||||
|
return
|
||||||
|
|
||||||
if self.attribute:
|
if self.attribute:
|
||||||
result = resolve_attribute(
|
result = resolve_attribute(
|
||||||
attribute=self.attribute, kwargs=self.kwargs,
|
attribute=self.attribute, kwargs=self.kwargs,
|
||||||
|
|||||||
@@ -48,8 +48,13 @@ def get_multi_item_links_form(context, object_list):
|
|||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.simple_tag(takes_context=True)
|
||||||
def get_source_columns(source):
|
def navigation_get_sort_field_querystring(context, column):
|
||||||
|
return column.get_sort_field_querystring(context=context)
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag(takes_context=True)
|
||||||
|
def navigation_get_source_columns(context, source, exclude_identifier=False, only_identifier=False):
|
||||||
try:
|
try:
|
||||||
# Is it a query set?
|
# Is it a query set?
|
||||||
source = source.model
|
source = source.model
|
||||||
@@ -68,7 +73,10 @@ def get_source_columns(source):
|
|||||||
# It a list and it's empty
|
# It a list and it's empty
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return SourceColumn.get_for_source(source)
|
return SourceColumn.get_for_source(
|
||||||
|
context=context, source=source, exclude_identifier=exclude_identifier,
|
||||||
|
only_identifier=only_identifier
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag(takes_context=True)
|
@register.simple_tag(takes_context=True)
|
||||||
@@ -107,6 +115,10 @@ def resolve_link(context, link):
|
|||||||
|
|
||||||
|
|
||||||
@register.simple_tag(takes_context=True)
|
@register.simple_tag(takes_context=True)
|
||||||
def source_column_resolve(context, column):
|
def navigation_source_column_resolve(context, column):
|
||||||
context['column_result'] = column.resolve(context=context)
|
if column:
|
||||||
return ''
|
result = column.resolve(context=context)
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user