Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get current URL kwargs in the template?

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 %}
like image 966
Dan Gamble Avatar asked Jul 19 '14 20:07

Dan Gamble


2 Answers

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 }}
like image 94
Anupam Avatar answered Nov 15 '22 06:11

Anupam


You can use dict.update():

update([other])

Update the dictionary with the key/value pairs from other, overwriting existing keys.

context.update(self.kwargs)
like image 20
alecxe Avatar answered Nov 15 '22 06:11

alecxe