2

I have developed a table, using django-tables2 which shows records of a model. The last column of this table, is an "edit button" which leads user to the "edit page" of its row record.

What I want is that the user can see the edit column only if she has permission to edit the model!

Also I need to mention that currently I'm using SingleTableView to develop table view.

Hamidreza
  • 1,465
  • 12
  • 31

2 Answers2

2

1: To make an entire column hidden, you can "exclude" that field from the table in the view.

class MyTableView(SingleTableView):
    # class based view
    model = MyModel
    table_class = MyTable

    def get_table(self, **kwargs):
        table = super(MyTableView, self).get_table(**kwargs)
        if not self.request.user.has_perm("can_edit"):
            table.exclude = ('edit_button',) 
        return table

def my_table_view(request):
    # function based view

    table = MyTable(<queryset>)

    if not request.user.has_perm("can_edit"):
        table.exclude = ('edit_button',) 

    [...]
    return render(request, template, context)

2: To hide the button in the column, you can check for permission before rendering the edit button by using a custom render function.

https://django-tables2.readthedocs.io/en/latest/pages/custom-data.html#table-render-foo-methods

class MyTable(tables.Table):

    edit_button = tables.Column()

    def render_edit_button(self, record):

        if request.user.has_perm("can_edit"):
            url = reverse("edit_view", args=(record.id,))

            return mark_safe(f'<a href="{url}">Edit {record.id}</a>')
        return mark_safe("")
Ben
  • 2,348
  • 1
  • 20
  • 23
  • I've tried using `TemplateColumn` before and its output was just like your solutions. The problem here is that the column is still there! but its cells is empty. What I'm looking for is a solution to don't show the column at all (when the condition is not satisfied!) – Hamidreza May 19 '21 at 04:47
  • @Hamidreza I've added some sample code for hiding the entire Django Tables column. – Ben May 19 '21 at 17:48
  • Tnx for your answer, I really appreciate it. But as I said, I am using `SingleTableView` and I don't want to change it to a functional-based view. I upvoted your answer as a thank you. – Hamidreza May 20 '21 at 15:06
  • @Hamidreza in the CBV you can use the `get_table()` method and incorporate the exclusion test. I've updated the code to show that example. – Ben May 20 '21 at 17:20
0

As I mentioned, I am using SingleTableView. So I found out there's a method in SingleTableView class, which according to its docs:

Allows passing customized arguments to the table constructor.

So to remove edit column, I added this method in my view class (which was inherited from SingleTableView:

    def get_table_kwargs(self):
            if not self.request.user.has_perm('permission_to_edit'):
                return {'exclude': ('edit_column',)}
            else:
                return {}
Hamidreza
  • 1,465
  • 12
  • 31