Django-tables2: Мета-параметры не наследуются.

Созданный на 15 июл. 2012  ·  17Комментарии  ·  Источник: jieter/django-tables2

Привет,

У меня есть следующие таблицы: -

    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')

Когда я визуализирую RoomTable сгенерированный <table> не имеет атрибута class . Я могу получить этот атрибут только тогда, когда я перемещаю (или копирую) класс Meta с BaseTable на RoomTable .

Это ошибка или я неправильно ее использую?

Все 17 Комментарий

Спасибо за отчет, это ошибка. Теперь это первое место в моем списке дел.

Спасибо.

Итак, я почти закончил реализацию решения этой проблемы, а затем я вспомнил, что для наследования Meta я следовал стилю Django, т.е.

class Meta(Parent.Meta):
    ...

Так что теперь я начинаю задаваться вопросом, действительно ли стоит отклоняться от этого. Я полагаю, что в любом случае это всегда было бессмысленно, в первом подклассе django_tables2.Table вам _не_ нужно делать class Meta(django_tables2.Tables): , но для любых дальнейших подклассов вы _до_.

Я полагаю, вы могли бы сказать, что django_tables2.Table.Meta API не существует, и он только _starts_ в первом подклассе. Что вы думаете об этом? Вы знали, как работает мета-наследование модели Django, и ожидали, что здесь все будет по-другому? Или вы были наивны по отношению к API Django и поэтому просто попробовали то, что показалось правильным?

Я только что перечитал вашу исходную проблему, и ваша проблема, похоже, в том, что вы даже не пытаетесь изменить мета-параметры в своем подклассе, вы просто пытаетесь создать подкласс и добавить столбцы.

Извините, я не совсем понимаю, что вы говорите, но да, то, что я сделал, было правильным. В любом случае, я новичок в вещах Meta, поэтому мой подход может быть не лучшим.

Брэдли,

Мне нравится работа над этим проектом. Я столкнулся с той же проблемой, что и здесь applegrew, и ваш последний комментарий полностью соответствует моему случаю.

### 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

Если определение класса Meta не помещено в ItemTable, метаатрибуты, установленные в родительском классе, не передаются. Я хотел бы, чтобы одинаковые атрибуты отправлялись во все таблицы в моих приложениях (которые в конечном итоге наследуются от MyAppTable)

Определение пустого класса Meta в ItemTable, который наследуется от родительского класса Meta (MyAppTable), работает, но, похоже, работает против принципа DRY, хотя это всего две строки и по-прежнему соответствует моему требованию о необходимости изменения класса CSS только в одной место, если мне нужно. Оцените работу! Спасибо.

Я знаю, откуда вы пришли, и склонен с вами согласиться, на самом деле я частично написал патч для реализации этого, однако этот подход противоречит подходу Django к моделям. Моя текущая позиция, однако, заключается в том, что для того, чтобы библиотека работала должным образом, важно, чтобы все работало аналогично Django.

Как вы думаете, действительно ли стоит отказаться от стандартного поведения Django + Python для этого?

Поскольку я разработал с использованием Django / Python всего около месяца, я не думаю, что у меня есть право приводить аргументы в пользу отхода от нормы. Я полагаю, что есть несколько вариантов. Ты мог бы:

a) Задокументируйте обходной путь, как описано выше (если это еще не сделано, я мог его пропустить). Это действительно не так уж и страшно.
б) Предоставьте атрибут, например, «inherit_meta = False», который можно переопределить в подклассах, чтобы позволить подклассам наследовать метаинформацию. По умолчанию было бы false, чтобы все работало в соответствии со стандартами Django, но это позволило бы более предприимчивым / ленивым людям, таким как я, устранить необходимость в повторяющихся определениях классов Meta. Единственная проблема, с которой я сталкиваюсь, - это сохранение дополнительного фрагмента кода для обходного пути, который потенциально может привести к ошибкам (данные присутствуют, когда не ожидаются) и т. Д.
c) Сделайте это поведение новым по умолчанию.

Даже когда я пишу это, я уже вижу в своей голове сценарии, в которых переменные шаблона проверяются на основе того факта, что наследование не происходит, происходит поломка, и я часами копаюсь в коде только для того, чтобы узнать, что он сломался, потому что я переопределить поведение вручную. Это также не соответствовало бы ни одному из существующих примеров.

Честно говоря, это не стоит усилий. Я бы предпочел увидеть дополнительную заметку о мета-наследовании 'gotcha' в документации, чем пытаться закодировать обходной путь для создания нетипичного поведения.

Что касается а), вы делаете это так:

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

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

Child.Meta теперь имеет foo = 1 _and_ bar = 2

Я склонен согласиться с тем, что это можно исправить с помощью документации.

Спасибо. У меня действительно было это в моем примере, основанном на примере Эпплгрю.

Угу, хорошее замечание.

Единственное раздражение, связанное с обходным решением, заключается в том, что вы не можете переопределить что-то в родительском классе:

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

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

поднимает NameError с name 'attrs' is not defined . Это, однако, похоже, работает, но некрасиво:

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

Есть ли решение этой ошибки? Вышеупомянутый обходной путь не работает для меня. http://stackoverflow.com/questions/21787938/inherit-and-modify-a-meta-class

Я не вижу очевидного алгоритма объединения двух произвольных class Meta . Подумайте о случаях добавления ключа к attrs , удаления ключа из attrs , замены attrs новым dict и т. Д. Может быть, я что-то упускаю, но это не так для меня очевидно, как бы вы сделали это разумным образом.

Поведение должно быть таким же, как если бы вы были подклассами models.Model classes.

Я не уверен, что понимаю, что вы говорите. Я просто пытаюсь унаследовать мета от родительского класса и добавить несколько столбцов. Я обновил код в вопросе SO выше, который, надеюсь, имеет немного больше смысла.

@bradleyayers - если я правильно понимаю ваш запрос, вы сможете подписаться на этот пост в

@pydolan Да, проверьте http://stackoverflow.com/questions/21787938/inherit-and-modify-a-meta-class и другие подходы.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги