1

I am working on my first django project and i am having problems displayin 'categories' from my database onto a webpage as a list. I am getting the error "object has no attribute 'Name'. My code so far is:

Model:

class Category(models.model):
    name = models.Charfield(max_length=128)

def __unicode__(self):
    return self.Name + ": " +str(self.id)

Views:

from django.shortcuts import render_to_response, redirect
from forms.models import Form, Group, Flow, Gate, Field, Event, Category
from django.core.context_processors import csrf
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse

def homepage (request):

    CatName = Category.objects.order_by('id')

    output = {
        'category_name': CatName.Name,
    }

    return render_to_response('forms/formsummary.html', output)

HTML:

<div>{{ category_name }}</div>

Can anybody point me in the right direction?

1
  • 2
    Remember that in Python, variable names are case-sensitive, so it should be CatName.name because that's the way you defined it in your model. You should also read the PEP8 styling guide for python code. Commented Dec 11, 2012 at 14:48

3 Answers 3

3

In Django, when you use the ORM to query for objects, there are two possibilities (excluding each case returning nothing):

  • Query returns just one objects: if so, you queried using the get() method of the manager.
  • Query returns a collection: if so, you queried by using an all(), filter() or any method like those.

In this case, your query returned a collection of Category objects, you can do a couple of things about this, you can either generate a list with only the names by using a list comprehension:

cnames = [c.name for c in Category.objects.all()]

Or you can iterate the list using a for loop and do whatever you need to do with each object.

Django already orders your data by the id field, so, I guess there is no need to specify an ordering in this case.

Later, when your view is returning, you can deliver the list to your template and iterate it to extract what you need, for example.

In your view:

def get_categories(request):
    categories = Category.objects.all()
    context = {'categories': categories}
    return render_to_response('template.html', RequestContext(request, context))

Then, in your template:

{% for c in categories %}
    <p>{{c.name}}</p>
{% endfor %}

Here's some useful documentation

Hope this helps.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the replies, but im lost again. Ive changed all my code to be in the correct case and removed the .Name from CatName.Name it now reads def homepage (request) CatName = Category.objects.order_by('id') ouput = { 'Category_Name': CatName, } return render_to_response('forms/formsummary.html', output) and <div>{{ Category_Name }}</div> This is seems to print out the categories, but along with the category id too like so: [<Catagory:Payroll:1>,<Category:SupportServices:2>] how can i change this so it just reads: Payroll, Support Services ?
CatName is a missleading variable name it might be better off as categories because that is what you have a collection of categories. Because you have multiple categories you need to iterate (diveintopython.net/file_handling/for_loops.html) over the collection of categories, you're on the right track you just need one more step, to go through all categories and print out their names israelord provides and example of how to do this in your template
As dm03514 said, CatName is a bad variable name in this case, you're storing all the categories there, so, a more useful name would be "categories", if you want to store only the name, you can do something like this: category_names = [c.name for c in Category.objects.all()]
STill cant get this to work. my View is now def homepage (request): Categories = [c.Name for c in Category.objects.al()] output = {'Category_Name': Categories,} return render_to_response('forms/formsummary.html', output) and in my template {% for c in Categories %}<p>{{ Category_Name }}</p>{% endfor %}. This is returning my template ok, but with the results??
in the views.py you should from django.template import RequestContext and in your particular view you should return render_to_response('your_template.html', RequestContext(request, output)). In your view, you should do: {% for c in Category_Name %} {{ c.name }} {% endfor %}. When in the template, fields are named like they correspondent key in your context dictionary.
1

It seems like case sensitive,

def__unicode__(self):
  return self.Name + ": " +str(self.id)
              ^
              name 

Comments

0

CatName is a collection of Category instances. The CatName object does not have a name property because it is not a Category object. It contains Category objects.

you can iterate through your collection and display each categories name:

for category in CatName:
  print category.name

It is good to at least read through QuerySet documentation even if you don't fully grasp it yet.

if you want just the most recent category you could do something like:

def homepage (request):

    most_recent_category = Category.objects.order_by('-id')[0]

    output = {
        'category_name': most_recent_category.name
    }

    return render_to_response('forms/formsummary.html', output)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.