Django-tables2: Les méta-options ne sont pas héritées.

Créé le 15 juil. 2012  ·  17Commentaires  ·  Source: jieter/django-tables2

Salut,

J'ai les tableaux suivants

    class BaseTable(tables.Table):
        select_column = tables.CheckBoxColumn(verbose_name='', empty_values=('NA',))

        class Meta:
            attrs = {'class' : 'cool_table'}

    class EditableTable(BaseTable):
        edit_column = EditIconColumn(verbose_name=_('Edit'))

        def set_editable(self, flag):
            if flag:
                self.base_columns['edit_column'].visible = True
            else:
                self.base_columns['edit_column'].visible = False   

    class RoomTable(EditableTable):
        number = tables.Column()
        speciality = tables.Column()
        photo = ImageViewColumn(accessor='room_type.photo')

Lorsque je rends RoomTable le <table> généré n'a pas l'attribut class . Je ne peux obtenir cet attribut que lorsque je déplace (ou copie) la classe Meta de BaseTable à RoomTable .

Est-ce un bug ou je ne l'utilise pas correctement ?

docs

Tous les 17 commentaires

Merci pour le rapport c'est un bug. C'est maintenant en haut de ma liste de choses à faire.

Merci.

J'ai donc presque fini d'implémenter une solution à cela, puis je me suis souvenu que pour l'héritage de Meta je suivais le style Django, c'est-à-dire

class Meta(Parent.Meta):
    ...

Alors maintenant, je commence à me demander si c'est vraiment une bonne idée de s'en écarter. Je suppose que cela a toujours été incohérent de toute façon, dans la première sous-classe de django_tables2.Table vous n'avez pas besoin de faire class Meta(django_tables2.Tables): , mais pour toute autre sous-classe, vous _faites_.

Je suppose que vous pourriez dire cependant qu'il n'y a pas d'API django_tables2.Table.Meta , et qu'elle ne démarre qu'à la première sous-classe. Quel est votre sentiment à ce sujet ? Saviez-vous comment fonctionne l'héritage Meta du modèle de Django et vous attendiez-vous à ce qu'il soit différent ici ? Ou étiez-vous naïf de l'API de Django et avez-vous simplement essayé ce qui vous semblait _bien_ ?

Je viens de relire votre numéro d'origine, et votre problème semble être que vous n'essayez même pas de modifier les méta-options dans votre sous-classe, vous essayez simplement de sous-classer et d'ajouter des colonnes.

Désolé, je ne comprends pas clairement ce que vous dites, mais oui, ce que j'ai fait était juste. Quoi qu'il en soit, je suis assez nouveau dans le domaine Meta, donc mon approche n'est peut-être pas bonne.

Bradley,

J'adore le travail sur ce projet. Je rencontre le même problème qu'applegrew ici, et votre dernier commentaire correspond parfaitement à mon cas.

### Table Definitions ###
# parent class 
import django_tables2 as tables

# generic parent class to handle table styling
class MyAppTable(tables.Table):
    class Meta:
        attrs = {'class': 'render-table'}


# subclass in a separate app
from myapp_helpers.tables import MyAppTable
from django_tables2.utils import A
import django_tables2 as tables

class ItemTable(MyAppTable):

    address_1 = tables.Column()
    address_2 = tables.Column()
    address_3 = tables.Column()
    city = tables.Column()
    state = tables.Column()
    zipcode = tables.Column()

    # need this to fix a bug with the meta class not passing through to subclasses in django-tables2
    class Meta(MyAppTable.Meta):
        pass


## Views ##

# class based view in separate app
from django_tables2 import SingleTableView

# Parent class to make pagination the same across views
class MyAppListView(SingleTableView):

    # default of 10 rows in every table on every page
    table_pagination = {"per_page": 10 }
    template_name = 'generic_list.html'


# subclass of view in local app
class ItemListView(MyAppListView):
    model = Item
    table_class = ItemTable

Si la définition Meta de classe n'est pas placée dans ItemTable, les attributs meta définis dans la classe parent ne sont pas envoyés. J'aimerais que les mêmes attrs soient envoyés à toutes les tables de mes applications (qui héritent éventuellement de MyAppTable)

Définir la classe Meta vide dans ItemTable qui hérite de la classe Meta parent (MyAppTable) fonctionne, mais semble aller à l'encontre du principe DRY, même s'il ne s'agit que de deux lignes et répond toujours à mon exigence de n'avoir besoin de changer la classe CSS qu'en une seule place si j'en ai besoin. Appréciez le travail ! Merci.

Je sais d'où vous venez, et j'ai tendance à être d'accord avec vous, en fait j'ai partiellement écrit un correctif pour implémenter cela, mais cette approche contredit l'approche de Django avec les modèles. Ma position actuelle est cependant qu'il est important que les choses fonctionnent de la même manière que Django pour que la bibliothèque fonctionne comme prévu.

Pensez-vous que cela vaut vraiment la peine de rompre avec le comportement standard de Django + Python pour cela ?

N'ayant développé à l'aide de Django/Python que depuis environ un mois, je ne pense pas être qualifié pour argumenter en faveur d'une rupture avec la norme. Je suppose qu'il y a quelques options cependant. Vous pourriez:

a) Documentez la solution de contournement comme indiqué ci-dessus (si ce n'est pas déjà fait, je l'ai peut-être manquée). Ce n'est vraiment pas terrible.
b) Fournissez un attribut comme 'inherit_meta = False' qui peut être remplacé dans les sous-classes pour permettre aux sous-classes d'hériter des méta-informations. La valeur par défaut serait false pour que les choses continuent de fonctionner selon les normes Django, mais permettrait aux personnes plus aventureuses / paresseuses comme moi d'éliminer le besoin des définitions répétées de la classe Meta. Le seul problème que je vois avec cela est le maintien d'un morceau de code supplémentaire pour une solution de contournement qui pourrait potentiellement introduire des bogues (données présentes alors qu'elles ne sont pas attendues), etc.
c) Faites de ce comportement la nouvelle valeur par défaut.

Même au moment où j'écris ceci, je peux déjà voir des scénarios dans ma tête où les variables de modèle sont vérifiées sur la base du fait qu'il n'y a pas d'héritage, que des cassures se produisent et que je passe des heures à fouiller dans le code pour découvrir qu'il s'est cassé parce que je outrepassé le comportement manuellement. Cela ne correspondrait pas non plus aux exemples existants.

Franchement, cela n'en vaut probablement pas la peine. Je préférerais voir une note supplémentaire sur le méta-héritage 'gotcha' dans la documentation plutôt que d'essayer de coder dans une solution de contournement pour générer un comportement atypique.

En ce qui concerne a), vous procédez comme ceci :

class Parent(tables.Table):
    class Meta:
        foo = 1

class Child(Parent):
    class Meta(Parent.Meta):
        bar = 2

Child.Meta maintenant foo = 1 _et_ bar = 2

J'ai tendance à convenir que cela peut être corrigé avec de la documentation.

Merci. En fait, j'avais cela dans mon exemple basé sur l'exemple d'applegrew.

Bon, bon point.

Un inconvénient avec la solution de contournement est que vous ne pouvez pas alors remplacer quelque chose dans la classe Parent :

class Parent(tables.Table):
    class Meta:
        attrs = {...}

class Child(Parent):
    class Meta(Parent.Meta):
         attrs = {'summary': 'A child table'}

lève un NameError avec name 'attrs' is not defined . Ceci, cependant, semble fonctionner, mais c'est moche:

class Child(Parent):
    class Meta(Parent.Meta):
        pass
     Meta.attrs['summary'] = 'A child table'

Existe-t-il déjà une solution à ce bug ? La solution de contournement ci-dessus ne fonctionne pas pour moi. http://stackoverflow.com/questions/21787938/inherit-and-modify-a-meta-class

Je ne vois pas d'algorithme évident pour fusionner deux class Meta arbitraires. Pensez aux cas d'ajout d'une clé à attrs , de suppression d'une clé de attrs , de remplacement de attrs par un nouveau dict, etc. Peut-être qu'il me manque quelque chose mais ce n'est pas le cas évident pour moi comment vous feriez cela d'une manière saine.

Le comportement devrait être le même que si vous étiez des sous-classes models.Model .

Je ne suis pas sûr de suivre ce que vous dites. J'essaie juste d'hériter de la méta de la classe parent et d'ajouter quelques colonnes. J'ai mis à jour le code dans la question SO ci-dessus, ce qui, espérons-le, a un peu plus de sens.

@bradleyayers -- si je comprends bien votre demande, vous devriez pouvoir suivre ce post StackOverflow pour écraser Meta

@pydolan Oui, consultez http://stackoverflow.com/questions/21787938/inherit-and-modify-a-meta-class pour d'autres approches également.

Cette page vous a été utile?
0 / 5 - 0 notes