views:

362

answers:

3

I have a simple view that I want to respond to both ajax and regular HTTP requests. Simplified, it looks like this:

def tag_search(request, tag):

    items = Item.objects.filter(tags__tagname__exact=tag)

    if request.is_ajax():

        return HttpResponse(serializers.serialize('json', items), mimetype='application/json')

    else:

        return render_to_response('mytemplate.html', locals())

The problem is that it isn't returning the values of the many to many relationships - just a list of the primary keys like:

[1, 2, 5]

I understand that I can't use select_related() to follow many to many relationships - can anyone provide me with a best practice for passing that information back, or an example?

+2  A: 

Update - it seems Django doesn't support this particularly well, but there's a third party serializer that does:

DjangoFullSerializers

John McCollum
+1  A: 

You may want to do a bulk select using those ids (probably the easiest solution)

item_ids = [1, 2, 5]
Item.objects.in_bulk(item_ids)

# Another option:
Item.objects.filter(id__in=item_ids)

edit: My advice is to either use django-tagging which handles this for you. OR just add a method to your Item model that gets the tags (and uses cache liberally)

from django.core.cache import cache

class Item(models.Model):
    ... 

    def get_tags(self):
        cache_key = "item_%s_tags" % self.id
        cache_timeout = 600  # 10 minutes or whatever

        tags = cache.get(cache_key, False)
        if not tags:
            tags = self.tags.all()
            cache.set(cache_key, tags, cache_timeout)

        return tags
Jiaaro
Thanks, it's an interesting idea, but how would I 'attach' the related objects to the main object for serialization? I get an error when I try to redefine item.tags with anything except a list of integers.
John McCollum
+1  A: 

I have written some code to do serialization in my project. It serializes model objects into dictionaries based upon a context, which describes how to serialize objects of each encountered type, so you may drop some fields from serialization or add new fields not present in the model. The code lacks comments, but you can find usage samples in unit tests. Hope that helps.

Dmitry Risenberg
Thanks for posting that - I'll check it out!
John McCollum