Rico
Rico

Reputation: 6052

Django model filter not pulling in object

I'm using Django 1.4 with Python 2.7 on Ubuntu 12.04.

I have a template that is supposed to show a product and a list of product features for each product and for some reason the features don't show in the template.

Here is the view:

@login_required
def view_products(request):
    """
    ..  function:: view_products()

        View the Products

        :param request: Django Request object
    """

    data = { 'user' : request.user }
    if (request.user.is_authenticated() and request.user.is_superuser):
        products = Products.objects.all()

        add_feature_form = rsb.forms.AddProductFeatureForm();
        data.update({ 'form' : add_feature_form })
        data.update({ 'products' : products })
        data.update(csrf(request))

        return render_to_response("view_products.html", data)

    return render_to_response("index.html", data)

Here is the portion of the template working with the product features:

<table>
    {% for product in products %}
        <tr>
            <td align="right">Product Name:</td><td>{{ product.name }}</td>
        </tr>
        <tr>
            <td align="right">Price:<br /></td><td>${{ product.price }}</td>
        </tr>
        <tr>
            <ul>
            {% for productfeature in product.productfeature_set.all %}
                <form action="/removeProductFeature/" method="post">{% csrf_token %}
                <li>
                    {{ productfeature.feature }}
                    <input type="hidden" name="feature" value={{ productfeature.feature }}>
                    <input type="hidden" name="product_id" value={{ product.id }}>
                    <label class="formlabel">&nbsp;</label><input type="submit" value="Remove  &#9658;">
                </tr>
                </form>
            {% endfor %}
            </ul>
        </tr>
        <tr>
            <form action="/addProductFeature/" method="post">{% csrf_token %}
            <table>
                <tr>
                    <td align="right"><label class="formlabel">Add Feature:<br /></label></td><td>{{ form.feature }}</td>
                </tr>
                <input type="hidden" name="product_id" value={{ product.id }}>
                <tr>
                    <td align="right"><label class="formlabel">&nbsp;</label></td><td><input type="submit" value="Add  &#9658;"></td>
                </tr>
            </form>
            </table>
        </tr>
   {% endfor %}
</table>

Basically this template should show you a product. Each feature will be listed below it with the option to "remove" that feature. Then, at the bottom, a field that allows you to add additional features.

The existing features do not show up at all. Any suggestions on what I might be doing wrong?

UPDATE 1:

I missed an s in the template. product.productfeatures_set.all not product.productfeature_set.all. I'm good to go. Thanks all!

Upvotes: 0

Views: 100

Answers (2)

A.J.Rouvoet
A.J.Rouvoet

Reputation: 1213

Yes, you are trying to implement something that is already build into Django!

You should use the build in reverse relations of django.

# give an Product instance product
# this should work
product.productfeature_set.all()

Which is accessible from the template a product.productfeature_set.all and can be itterated over.

Upvotes: 1

jpic
jpic

Reputation: 33420

Please don't do this:

product_features = []
for product in products:
    features = ProductFeatures.objects.filter(product = product)
    product_features.append(features)
    product.features = product_features

Instead, just pass your products variable to the template context.

And in the template do:

{% for product in products %}
    Product id: {{ product.pk }}
    {% for productfeature in product.productfeature_set.all %}
        {{ productfeature.feature }}
    {% endfor %}
{% endfor %}

What is productfeature_set you would ask (or, I hope you would ask :D), and that's a very good question. Don't panic, it's all documented.

Now, this is going to cause subqueries to spawn. The solution is to use prefetch_related. But you don't have to worry about that for the moment I think :)

Upvotes: 3

Related Questions