2

Mit Djang-tables2 benutzerdefinierte Tabelle verwenden, wie:Wie Benutzerberechtigungen in django-tables2 Spalte

tables.py:

import django_tables2 as tables 
from django_tables2.utils import A 
from .models import Person 

class PersonTable(tables.Table): 

    view_column = tables.LinkColumn('person:pessoas_detail', args=[A('pk')]) 

    class Meta: 
     model = Person 

views.py:

from .models import Person 

class ListView(SingleTableView): 
    model = Person 
    table_class = PersonTable 

ich brauche Überprüfen Sie die Berechtigung FOO in der Spalte view_column. Da view_column ein Klassenattribut ist, kann ich einen Decorator nicht als @permission_required verwenden.

Wahrscheinlich könnte ich etwas anderes als tables.LinkColumn aufrufen, um die Berechtigung zu testen und dann die Spalte zurückzugeben. Dazu müsste ich jedoch auf das Benutzerobjekt zugreifen (wahrscheinlich aus dem Anfrageobjekt), auf das ich zu diesem Zeitpunkt keinen Zugriff hätte.

Gibt es einen einfacheren Weg, dies zu tun?

Grundsätzlich besteht die Idee darin, eine Spalte nur dann anzuzeigen, wenn ein Berechtigungszugriff darauf besteht oder überhaupt nicht angezeigt wird.

Antwort

1

Ich denke, dass der einfachere Weg zu tun, was Sie wollen, ist einfach eine Vorlage Spalte zu verwenden (das ist, was ich tue):

view_column = tables.TemplateColumn(""" 
    {% if has_perm('FOO') %} 
    <a href='{% url "person:pessoas_detail" record.id %}>{{ record.id }}</a> 
    {% else %} 
    {{ record.id }} 
    {% endif %} 
""", orderable=False) 

Nun, wenn der Benutzer die entsprechende Berechtigung hat, dann wird es den Link angezeigt werden - Wenn nicht, wird nur die ID jedes Datensatzes angezeigt.

+0

Das hat zwei Nachteile, wie ich sehen kann. Die Spalte ist nicht optional. Ich weiß, dass es nicht gefragt wurde, aber es ist, was Sie erhalten, wenn die Erlaubnis überprüft wurde, bevor Sie das Spaltenobjekt zurückgaben. Es scheint auch eine große Leistungsstrafe zu sein. – rsd

+0

Ich fange an zu denken, dass dies die einzige Lösung sein könnte. Django speichert den Ausführungscode zwischen, so dass ich nicht weiß, ob es vertrauenswürdig ist, dass die nächste Anfrage für denselben Benutzer erfolgt. django-tables2 verwendet die Methode __new__, um Informationen zu den Spalten zu sammeln, wodurch weniger Platz für eine Klassenattributmanipulation zur Verfügung steht. – rsd

+0

Wie gesagt, ich verwende diese Lösung in ähnlichen Fällen. Es gibt keine Leistungseinbußen, wenn Sie Seitenumbrüche für die Tabelle verwenden (d. H. Weniger als 100 Zeilen pro Seite darstellen). Es gibt andere Lösungen, aber Sie müssen dann wahrscheinlich die Tabelle in der Ansicht manipulieren (oder definieren Sie zwei Tabellen eine mit der Spalte view_column und eine ohne sie und rendern Sie die richtige je nach Berechtigungen - nicht DRY). – Serafeim

0

Try Before_Render-Funktion.

Example:: 
     class Table(tables.Table): 
      name = tables.Column(orderable=False) 
      country = tables.Column(orderable=False) 
      def before_render(self, request): 
       if request.user.has_perm('foo.delete_bar'): 
        self.columns.hide('country') 
       else: 
        self.columns.show('country')