Question

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 %}
Was it helpful?

Solution

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).

OTHER TIPS

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.

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 %}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top