views:

40

answers:

2

The description below is heavily simplified - it's only one part of a bigger problem that we are tackling but the innards can be safely left out for this question.

Suppose we have the following models: -

class Item(models.Model):
    name = models.CharField(max_length=150)
    value = models.DecimalField(max_digits=12,decimal_places=2)

class Person(models.Model):
    name = models.CharField(max_length=150)
    items = models.ManyToManyField(Item, through='AssignedItem')

class AssignedItem(models.Model):
    person = models.ForeignKey(Person)
    item = models.ForeignKey(Item)
    value = models.DecimalField(max_digits=12,decimal_places=2)

So basically a person may be assigned zero, one, or more items and each assigned item's value may be overridden for a particular person by specifying the new value in the through model.

What we are aiming to achieve is an html table which has all the Item.name as its header row, with one extra column in that header row for Person.name.

Each Person may have a different set of Person.items assigned to them so it is expected that if a Person has not been assigned an Item, the corresponding cell for that Person will be blank (please see attached image).

alt text

The question is how to place the correct AssignedItem value in the corresponding column. We have a Queryset of Items that we are looping over in the template to create the header row, and then we have a list of lists containing each person's items. But how do we ensure that the correct AssignedItem is displayed under the corresponding Item header?

A: 

You mentioned you are constructing the list in the view,

We have a Queryset of Items that we are looping over in the template to create the header row, and then we have a list of lists containing each person's items.

When constructing this list, make the list an ordered list, where if a particular value exists, assign it and if it doesnt, then insert None. ie, the list for Jake should look like [78, 45, None, 94, 72]

Edit: Since reordering is an issue, use a dictionary with the item as index ie, the values for Jake should look like {'Item1':78, 'Item2':45, 'Item4':94, 'Item5':72}

zsquare
That is one way to go about it. But like I said, this is part of a bigger process and changing the order pre-process or post-process does not suit the situation. But yes, we will try this out, see if can rearrange and items post-process without gravely affecting the code that follows.
chefsmart
or instead of reordering, use a dictionary instead of the list, with the item as index. If a value exists in the dictionary, print the value, else display None. So the Jake values would become: {'Item1':78, 'Item2':45, 'Item4':94, 'Item5':72}
zsquare
A: 

Well, the main issue was to ensure that the correct AssignedItem is displayed under the corresponding Item header.

I tried a lot of things in the template, but it did not offer too much room to maneuver. I ultimately created the "table" in the view then passed the string to the template for rendering.

chefsmart