0

I am making a shopping website using django 1.4, I am displaying my products as a list view, when I try to pass the id of a product to a url pattern, I keep getting the below error. so my list of products does not load.

Reverse for 'view_item' with arguments '('',)' and keyword arguments '{}' not found.

list_products.html

<td class="vertical-center"><a href="{% url view_item item_id %}">{{ item_id }}</a></td>

urls.py

url(r'^view_item/(?P<item_id>\w+)', 'view_item', name="view_item"), 
Percy3872
  • 17
  • 7
  • 2
    You need to include the `item_id` in the template context. The message `arguments '('',)'` is telling you that `item_id` is missing from the context. You haven't shown the view so we can't help any more. – Alasdair Jan 31 '17 at 17:23
  • 3
    Why are you making a new website using an old, unsupported Django version? You should upgrade to a supported version. – knbk Jan 31 '17 at 17:23
  • @kbnk Very true. I'll remove the previous comment as it's not helpful to the problem here. Thanks for pointing that out – Alex Jillard Jan 31 '17 at 17:32
  • I am looping through the records in the list view, so how would I pass the ID through before I have looped through the records on the list view – Percy3872 Jan 31 '17 at 19:41
  • In that case, please show some more of your template. If you don't pass in `item_id` from the view, you still need to make sure it is available as a (locally-scoped) variable when you use it. – knbk Jan 31 '17 at 19:56

1 Answers1

0

There is a few ways to route urls First Class Based then Function Based

Given an example:

Models.py

from django.db import models
from django.core.urlresolvers import reverse

# Create your models here.
class Item(models.Model):
    name = models.CharField(max_length = 120)
    description = models.TextField(blank = True, null = True)
    price = models.DecimalField(decimal_places = 2, max_digits = 20)

    def __unicode__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('item_detail', kwargs = {'pk' : self.pk})
# this function will return  the url for item_detail with primary key
# url(r'^items/(?P<pk>\d+)/$', ItemDetailView.as_view(), name = 'item_detail'),
#here we are matching a url to pk and specify that id is a digit
# then set the class Based View
# then set the name of the url
# Primary key is automaticaly added by django, to every object 
# it is same as id.

Views.py: Class Based

from django.shortcuts import render
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView

# Create your views here.
from .models import Item

class ItemListView(ListView):
    model = Item
    template_name = 'list_view.html'

    def get_context_data(self, **kwargs):
        context = super(ItemListView, self).get_context_data(**kwargs)
        return context

class ItemDetailView(DetailView):
    model = Item
    template_name = 'detail_view.html'

    def get_context_data(self, **kwargs):
        context = super(ItemDetailView, self).get_context_data(**kwargs)
        return context

urls.py

from items.views import *

urlpatterns = [
    url(r'^items/$', ItemListView.as_view(), name = 'items'),
    url(r'^items/(?P<pk>\d+)/$', ItemDetailView.as_view(), name = 'item_detail'),
]

list_view.html!!!!!!YOUR Answer is HERE!!!

{% extends "base.html" %}

{% block content %}

<br><br><br>
{% for item in item_list%}
<a href='{{item.get_absolute_url}}'><p>{{item.name}}</p></a>
<!-- these wil work exactly the same. How ever the first version is the most reliable. -->

<a href='{% url "item_detail" pk=item.pk %}'><p>{{item.name}}</p></a>
<!-- These are also Identical. How ever For class BASED VIEWS you MUST use
either Primary Key or a SLUG!!! -->

<a href='{% url "item_detail" pk=item.id %}'><p>{{item.name}}</p></a>

{% endfor%}


{% endblock content %}

detail_view.html

{% block content %}
<br><br><br>
<br><br><br>

<table class="table">

<tr>
<td>{{object.id}}</td>
<td>{{object.name}}</td>
<td>{{object.pk}}</td>
<td>{{object.description}}</td>
<td>{{object.price}}</td>
</tr>
</table>
{% endblock content %}

Views.py Function based

def item_detail_view_func(request, id):
    item_instance = Item.objects.get(id =id)
    template = 'detail_view.html'
    context = {}
    context['object'] = item_instance
    return render(request, template, context)

Urls.py

url(r'^items/(?P<id>\d+)/$', item_detail_view_func, name = 'item_detail'),

list_view.html!!!!!!YOUR Answer is HERE!!!

{% for item in item_list%}
<!-- this version of urls will only work with function base views!!! -->
<a href='{% url "item_detail" id=item.id %}'><p>{{item.name}}</p></a>
{% endfor%}
nodefault
  • 372
  • 3
  • 7