tags:

views:

70

answers:

2

I have the following model:

class Channel(models.Model):
    tags = models.ManyToManyField(Tag)

class Tag(models.Model):
    name = models.CharField( primary_key = True)

And want to get_or_create a channel that has exactly the given set of tags.

tags = map(lambda x: Tag.objects.get(name = x), ['tag1', 'tag2'])
channel = Channel.objects.get_or_create(tags = tags) # Here's the bug

Edit: looks like the problem is with the create part, because

Channel.objects.get(tags=tags)

works just fine. So it is the usual problem with saving a many-many relationship.

A: 

What about something like:

tags = Tag.objects.filter(name__in=['tag1', 'tag2'])
channel = Channel.objects.get_or_create(tags=tags)
Josh Ourisman
Does not work - it has the same problem as my code in the second line. See update.
Dmitry Risenberg
+1  A: 

I don't think you can use get_or_create in this case. You need to do it in multiple steps:

  1. filter you channel list to get the channels with that exact list of tags, if there is one
  2. if the list is empty, create your channel and add the tags after the channel is created and has an ID

Ex:

tags = ['tag1', 'tag2']
channel = reduce(lambda channel_filter, x: channel_filter.filter(tags__name=x), tags, Channel.objects) # not checking if only one objetct is returned
if not channel:
    channel = Channel()
    channel.save()
    map(channel.tags.add, [Tag.objects.get(name = x) for x in tags])