0

Gradding a random image causes the title, url (etc) attributes on the tag.rand_img to vanish, meaning I can't display anything more than the object name.

view.py:

def locations_gallery(request):
  queryset = Photo.objects.all()
  tags = Tag.objects.usage_for_queryset(queryset, counts=True)
  tags.sort(key=operator.attrgetter('count'), reverse=True)
  for tag in tags:
    image_tag = Tag.objects.get(name=tag)
    tag.rand_img = TaggedItem.objects.get_union_by_model(Photo, image_tag).order_by('?')[:1]
  ctxt['tags'] = tags
  return render_to_response('locations_gallery.html', ctxt, RequestContext(request))

Template (simplified):

{% for tag in tags %}
{{ tag.name }}
<img src="{{ tag.rand_img.url }}">
{% endfor %}
Rob B
  • 1,514
  • 3
  • 23
  • 38

3 Answers3

2

This line:

tag.rand_img = TaggedItem.objects.get_union_by_model(Photo, image_tag).order_by('?')[:1]

is returning a Queryset, not a model instance. The queryset doesn't have your custom methods, they exist only on the instance within that queryset.

Replace the [:1] with [0] to get the actual model instance (you'll need to catch IndexError in case there isn't a matching item).

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
1

I'd first get the tags:

tags = Tag.objects.usage_for_queryset(queryset, counts=True)
tags.sort(key=operator.attrgetter('count'), reverse=True)

and then iterate through them and add the image as an extra field. Then you could do something like you've outlined in your template.

Laur Ivan
  • 4,117
  • 3
  • 38
  • 62
  • How do you add the image as an extra field? That's the bit I'm stuck on. – Rob B Jan 31 '12 at 10:51
  • 1
    I think just doing a `tag.rand_img = img` should suffice. – Laur Ivan Jan 31 '12 at 11:03
  • tag.rand_img = tag causes the object to lose all its attributes like title, url etc – Rob B Jan 31 '12 at 11:23
  • 1
    That's not right... [Python doc](http://docs.python.org/tutorial/classes.html#odds-and-ends) says that you can add a field later on to the class. ...and it should be "... = img" , not "... = tag" :) – Laur Ivan Jan 31 '12 at 11:30
  • Thanks, thats just a typo. I think the line TaggedItem.objects.get_union_by_model(Photo, image_tag).order_by('?')[:1] is removing the extra attributes I need. I'll update the code above. – Rob B Jan 31 '12 at 11:45
1

You can add attributes like that, Python will allow it but then you are no longer working on a QuerySet.

Try this:

def get_rand_img(tag):
   return TaggedItem.objects.get_union_by_model(Photo, tag).order_by('?')[:1]

display_tags = [(Tag.objects.get(name=tag),
                 get_rand_img(Tag.objects.get(name=tag))) for tag in tags]
ctxt['tags'] = display_tags

Then in your view

{% for tag, rand_img in tags %}
   {{ tag.name }}
   <img src="{{ rand_img.url }}">
{% endfor %}
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284