morlandi / django-ajax-datatable

A Django app which provides the integration of a Django project with the jQuery Javascript library DataTables.net
MIT License
211 stars 64 forks source link

Showing related objects as columns. Howto? #47

Open byte-for-byte opened 3 years ago

byte-for-byte commented 3 years ago

Hi, I just found this package: Thanks already for providing this awesome piece of work! I was wondering if I could use it for my 1-to-many situation though:

I have two Django models, Item and Prop. Each Item can have up to 2 related Prop objects where Prop.ptype isalways in ['P1', 'P2']. (In reality, there are many more Prop ptypes).

class Item(models.Model):
    name = models.TextField(blank=True, null=True)

class Prop(models.Model):
    ptype = models.TextField(blank=True, null=True)
    value = models.TextField(blank=True, null=True)
    item = models.ForeignKey(Item, on_delete=models.CASCADE)

# add some content
i1 = Item.objects.create(name='I1')
i2 = Item.objects.create(name='I2')
Prop.objects.create(ptype='P1', value='a', item=i1)
Prop.objects.create(ptype='P2', value='b', item=i1)
Prop.objects.create(ptype='P1', value='x', item=i2)

This situation in the database:

> select * from item;
 id | name |
----+------+-
  1 | I1   |
  2 | I2   |

> select * from prop;
 | ptype | value | item_id |
-+------+-------+---------+-
 | P1   | a     | 1       |
 | P2   | b     | 1       |
 | P1   | x     | 2       |

For all Item objects, I want to display a datatable of the following format:

 Name | P1 | P2 |
------+----+----+-
  I1  | a  | b  |
  I2  | x  | -  |

I can do this by using:

from . models import Item, Prop
class AjaxTest_Callback(AjaxDatatableView):
    model = Item
    initial_order = [['name', 'asc'], ]
    PROP_TYPES = ['P1', 'P2']

    # first column is item id
    column_defs = [
        {'name': 'name', 'visible': True, 'searchable': False},
    ]

    # add prop columns for all properties
    for p in PROP_TYPES:
        column_defs.append({'name': p, 'visible': True, 'searchable': False, 'orderable': True})

    # row by row, add foreign key values to the prop columns
    def customize_row(self, row, obj):
        for p in self.PROP_TYPES:
            entry = obj.prop_set.filter(ptype=p)
            row[p] = entry[0].value if entry else '-'

However, if i want to have the prop columns searchable, this does not work any more since P1/P2/P3 are not part of the Item model. So I assume my approach is not good after all. I was looking into defining foreign_field entries in column_defs, but I do not see how this could we used to solve my problem.

Could somebody pls give me a pointer to the right direction?

TIA

henryfool91 commented 2 years ago

Same question, it would be greate if we could get foreign keys as columns, may be somebody could give some tips or direction? Anyway, thanks @morlandi for such an eazy-to-use and great app!

morlandi commented 2 years ago

Thank you @byte-for-byte for sharing your analisys.

I do understand this need; see also #22 issue which I wrote some time ago on the same subject.

Let's keep this issue open, hoping to receive a PR on this sooner or later (maybe by myself when time allows)