Привет,
У меня есть следующие таблицы: -
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
.
Это ошибка или я неправильно ее использую?
Спасибо за отчет, это ошибка. Теперь это первое место в моем списке дел.
Спасибо.
Итак, я почти закончил реализацию решения этой проблемы, а затем я вспомнил, что для наследования 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 и другие подходы.