I'm accomplishing this at the moment by doing:
context['card_type'] = self.kwargs['card_type']
context['role_line'] = self.kwargs['role_line']
context['sort_by'] = self.kwargs['sort_by']
Which seems crazy counter intuitive to me.
Say if i was already at the urls of players/one/two/three
Is there an already prebuilt way to get current kwargs of one, two & three
for use in templates?
Edit
urls.py
urlpatterns = patterns('',
url(
r'^$',
NationListView.as_view(),
name='index'
),
url(
r'^(?P<slug>[a-z-]*)/$',
NationDetailView.as_view(),
name='nation'
),
url(
r'^(?P<slug>[a-z-]*)/(?P<card_type>[a-z]*)/(?P<role_line>[a-z]*)/(?P<sort_by>[a-z0-9]*)/$',
NationDetailFilteredView.as_view(),
name='nation_filter'
),
)
The mixin that builds the context
class CoreDetailFilteredMixin(object):
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(CoreDetailFilteredMixin, self).get_context_data(**kwargs)
base_objects(context)
# Pull all the players that belong to the object_type
context['players'] = Player.objects.filter(
**{filters: context['object'].asset_id}
)
# Define the available card types
card_types = {
'if': {'card_type__gte': 2},
'gold': {'overall_rating__gte': 75},
'silver': {'overall_rating__range': (65, 74)},
'bronze': {'overall_rating__lte': 64}
}
# Check if the given card type is in the dictionary because 'all' throws an KeyError
if self.kwargs['card_type'] in card_types:
context['players'] = context['players'].filter(**card_types[self.kwargs['card_type']])
# Don't show inform cards for specific colour card types
if self.kwargs['card_type'] not in ['if', 'all']:
context['players'] = context['players'].exclude(card_type__gte=2)
# Define available role lines
role_lines = {
'att': 3,
'mid': 2,
'def': 1,
'gk': 0
}
# Check if the given role line is in the dictionary because 'all' throws an KeyError
if self.kwargs['role_line'] in role_lines:
context['players'] = context['players'].filter(role_line=role_lines[self.kwargs['role_line']])
# Define the available sort by keys
sorts = {
'ovr': 'overall_rating',
'att1': 'card_att1',
'att2': 'card_att2',
'att3': 'card_att3',
'att4': 'card_att4',
'att5': 'card_att5',
'att6': 'card_att6r'
}
# Add a descending order to the existing queryset
context['players'] = context['players'].order_by('-' + sorts[self.kwargs['sort_by']])
# Create pagination
cbv_pagination(self, context, context['players'], 28, 'players')
context['card_type'] = self.kwargs['card_type']
context['role_line'] = self.kwargs['role_line']
context['sort_by'] = self.kwargs['sort_by']
return context
How i use it currently in the template
{% with object.get_class_name|add:'s'|add:':'|add:object.get_class_name|add:'_filter'|lower as url_string %}
<dl class="sub-nav">
<dt>Card Type:</dt>
{% with 'all if gold silver bronze' as card_types %}
{% for ct in card_types.split %}
{% cycle 'All' 'Inform' 'Gold' 'Silver' 'Bronze' as card_type_name silent %}
{% if card_type == ct %}
<dd class="active">
{% else %}
<dd>
{% endif %}
<a href="{% url url_string object.slug ct role_line|default:'all' sort_by|default:'ovr' %}">
{{ card_type_name }}
</a>
</dd>
{% endfor %}
{% endwith %}
</dl>
<dl class="sub-nav">
<dt>Role Line:</dt>
{% with 'all att mid def gk' as role_lines %}
{% for rl in role_lines.split %}
{% cycle 'All' 'Attackers' 'Midfielders' 'Defenders' 'Goalkeepers' as role_lines_name silent %}
{% if role_line == rl %}
<dd class="active">
{% else %}
<dd>
{% endif %}
<a href="{% url url_string object.slug card_type|default:'all' rl sort_by|default:'ovr' %}">
{{ role_lines_name }}
</a>
</dd>
{% endfor %}
{% endwith %}
</dl>
<dl class="sub-nav">
<dt>Sort By:</dt>
{% with 'ovr att1 att2 att3 att4 att5 att6' as sorts %}
{% for sort in sorts.split %}
{% ifequal role_line 'gk' %}
{% cycle 'Overall' 'Diving' 'Handling' 'Kicking' 'Reflexes' 'Speed' 'Positioning' as sorts_name silent %}
{% else %}
{% cycle 'Overall' 'Pace' 'Shooting' 'Passing' 'Dribbling' 'Defending' 'Heading' as sorts_name silent %}
{% endifequal %}
{% if sort_by == sort %}
<dd class="active">
{% else %}
<dd>
{% endif %}
<a href="{% url url_string object.slug card_type|default:'all' role_line|default:'all' sort %}">
{{ sorts_name }}
</a>
</dd>
{% endfor %}
{% endwith %}
</dl>
{% endwith %}
As I learnt here, the view is already passed to the context (for class-based views). So you can do the following in the template without needing to explicitly pass the kwargs from the view:
{{ view.kwargs.card_type }}
{{ view.kwargs.role_line }}
{{ view.kwargs.sort_by }}
You can use dict.update()
:
update([other])
Update the dictionary with the key/value pairs from other, overwriting existing keys.
context.update(self.kwargs)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With