views:

40

answers:

3

My models:

class ItemSet(models.Model):
    name = models.CharField(max_length=30)
    item = models.ManyToManyField(Item)
    order = models.IntegerField(default=0)

class Item(models.Model):
    name = models.CharField(max_length=30)
    desc = models.CharField(max_length=100)

A set includes many items and a item can be in many sets. So, how to get a list of items when we know the id of a item in some sets but itself? Please give me some codes. Thank you very much!

Example: We have two sets like this: (1,2,3,4) and (2,3,5,7,9), id = 3 then result = (1,2,4,5,7,9). Note: result does not include 3.

+3  A: 

Get all Items in a specific ItemSet:

set = ItemSet.objects.get(id=99)
items = set.item.all()

Get all ItemSets containing a specific Item:

item = Item.objects.get(id=88)
sets = item.itemset_set.all()

For more info - read the docs.

Yuval A
Just because I have a large number of the items. I want to choose a best way for queries. Thanks!
Tran Tuan Anh
Start off the traditional way. Optimize as necessary. Never prematurely.
Yuval A
A: 

Do you really need a ManyToManyField foreign key for this?

maraujop
This is a question, not an answer.
Yuval A
Really? Thanks for your appreciation, sometimes questions are better than answers. I was just pointing that maybe he is not using the right foreign key and is making things more complex than necessary.
maraujop
+1  A: 

If I understand your question correctly, you want a distinct set of all items from all ItemSets which contain a specific Item, excluding the Item itself from the returned set. Does that sound about right?

Edit: Tested.

class ItemSet(models.Model):
    name = models.CharField(max_length=30)
    items = models.ManyToManyField('Item', related_name='item_sets')
    order = models.IntegerField(default=0)

class Item(models.Model):
    name = models.CharField(max_length=30)
    desc = models.CharField(max_length=100)

# First, get all sets containing the item we're interested in:
item_sets = ItemSet.objects.filter(items__pk=item.pk)
# Next, get all items belonging to those sets, excluding the item we're interested in:
items = Item.objects.filter(item_sets__pk__in=item_sets).exclude(pk=item.pk).distinct()

Note: This actually executes a single query (using Django 1.2.1), though, this might depend on your database backend. You can examine the generated SQL like so:

>>> from django.db import connection
>>> items._as_sql(connection)
...
elo80ka