Search code examples
djangodjango-tables2

How to add hidden input for ID field inside django-tables2?


I am using Django-tables2 to render a table that has form tags wrapped around the table in order to save modified row order data. I need to have the table render the following hidden input inside the form tags so my form can save the modified data.

<input type="hidden" name="id" value="{{ track.id }}">

The solution works, but it currently renders the input tags inside the td tags, which makes it show the ID column. How do I hide the ID column while still having the hidden input tags?

<td class="id">20098<input type="hidden" name="track_id" value="20098" /></td>

tables.py:

class TrackIDColumn(tables.Column):

    def render(self, value):
        return mark_safe(str(value) + '<input type="hidden" name="track_id" value="' + str(value) + '" />')

class PlaylistTable(tables.Table):

    id = TrackIDColumn()

    class Meta:
        model = Track
        attrs = {"class": "paleblue"}
        orderable = False
        fields = ('id', 'artist', 'title',)

template:

<form method='POST' action='{% url "playlists:save_playlist" username=user.get_username slug=playlist.slug %}'>{% csrf_token %}
{% render_table table "django_tables2/bootstrap.html" %}
<button type="submit" name="playlist_id" value="{{ playlist.id }}" class="btn btn-primary">Save</button>
</form>

Solution

  • You cannot render someting in a column without rendering a column. What you can do is hide the header by adding an empty verbose_name on the column:

    class PlaylistTable(tables.Table):
        id = tables.Column(verbose_name='')
    
        def render_id(self, value):
            return format_html('<input type="hidden" name="track_id" value="{}" />', str(value))
    

    If you absolutely do not want an extra column to be rendered, you'll have to add the hidden input tag to another column:

    class PlaylistTable(tables.Table):
        artist = tables.Column()
        title = tables.Column()
    
        def render_title(self, value, record):
            return format_html('{} <input type="hidden" name="track_id" value="{}" />', value, record.id)