Django-tables2: Las meta opciones no se heredan.

Creado en 15 jul. 2012  ·  17Comentarios  ·  Fuente: jieter/django-tables2

Hola,

Tengo las siguientes tablas: -

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

Cuando renderizo RoomTable el <table> generado no tiene el atributo class . Puedo obtener ese atributo solo cuando muevo (o copio) la clase Meta de BaseTable a RoomTable .

¿Es esto un error o lo estoy usando incorrectamente?

docs

Todos 17 comentarios

Gracias por el informe, esto es un error. Ahora está en la parte superior de mi lista de tareas pendientes.

Gracias.

Así que casi terminé de implementar una solución para esto, y luego recordé que por Meta herencia estaba siguiendo el estilo Django, es decir

class Meta(Parent.Meta):
    ...

Así que ahora estoy empezando a preguntarme si en realidad es una buena idea desviarse de eso. Supongo que siempre ha sido inconsistente de todos modos, en la primera subclase de django_tables2.Table usted _no_ necesita hacer class Meta(django_tables2.Tables): , pero para otras subclases usted _hace_.

Sin embargo, supongo que podría decir que no hay django_tables2.Table.Meta API, y solo _ comienza_ en la primera subclase. ¿Qué opinas de esto? ¿Sabías cómo funciona la herencia Meta del modelo de Django y esperas que sea diferente aquí? ¿O era ingenuo con la API de Django y simplemente probó lo que se sintió _correcto_?

Acabo de volver a leer su problema original, y su problema parece ser que ni siquiera está tratando de cambiar las opciones meta en su subclase, solo está tratando de crear una subclase y agregar columnas.

Lo siento, no entiendo claramente lo que estás diciendo, pero sí, lo que hice fue que me sentí bien. De todos modos, soy bastante nuevo en las cosas de Meta, por lo que mi enfoque puede no ser bueno.

Bradley,

Amo el trabajo en este proyecto. Me encuentro con el mismo problema que applegrew aquí, y su último comentario coincide perfectamente con mi caso.

### 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 metadefinición de la clase no se coloca en ItemTable, los meta atributos establecidos en la clase principal no se envían. Me gustaría tener los mismos atributos enviados a todas las tablas en mis aplicaciones (que eventualmente heredarán de MyAppTable)

Definir la clase Meta vacía en ItemTable que hereda de la clase Meta principal (MyAppTable) funciona, pero parece funcionar en contra del principio DRY, aunque solo son dos líneas y aún cumple con mi requisito de solo necesitar cambiar la clase CSS en una lugar si lo necesito. ¡Aprecia el trabajo! Gracias.

Sé de dónde vienes y suelo estar de acuerdo contigo, de hecho, he escrito parcialmente un parche para implementar esto, sin embargo, este enfoque contradice el enfoque que Django toma con los modelos. Sin embargo, mi postura actual es que hacer que las cosas funcionen de manera similar a Django es importante para que la biblioteca funcione como se esperaba.

¿Crees que realmente vale la pena romper con el comportamiento estándar de Django + Python para esto?

Después de haberme desarrollado usando Django / Python durante aproximadamente un mes, no creo que esté calificado para presentar un argumento para romper con la norma. Sin embargo, supongo que hay algunas opciones. Tú podrías:

a) Documente la solución alternativa como se detalla anteriormente (si aún no lo está, es posible que me lo haya perdido). Realmente no es tan terrible.
b) Proporcione un atributo como 'heritage_meta = False' que se pueda anular en las subclases para permitir que las subclases hereden la metainformación. El valor predeterminado sería falso para mantener las cosas funcionando de acuerdo con los estándares de Django, pero permitiría a las personas más aventureras / perezosas como yo eliminar la necesidad de las definiciones repetidas de la clase Meta. El único problema que veo con eso es mantener un fragmento adicional de código para una solución que podría introducir errores (datos presentes cuando no se esperan), etc.
c) Haga que este comportamiento sea el nuevo predeterminado.

Incluso mientras escribo esto, ya puedo ver escenarios en mi cabeza donde las variables de la plantilla se verifican en función del hecho de que no se produce la herencia, se produce la rotura y paso horas hurgando en el código solo para descubrir que se rompió porque anuló el comportamiento manualmente. Tampoco coincidiría con ninguno de los ejemplos existentes.

Francamente, probablemente no valga la pena el esfuerzo. Preferiría ver una nota adicional sobre la herencia meta 'gotcha' en la documentación que intentar codificar una solución alternativa para generar un comportamiento atípico.

En lo que respecta a a), lo haces así:

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

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

Child.Meta ahora tiene foo = 1 _and_ bar = 2

Tiendo a estar de acuerdo en que esto se puede solucionar con documentación.

Gracias. De hecho, tuve esto en mi ejemplo basado en el ejemplo de applegrew.

Doh, buen punto.

Una molestia con la solución es que no puede anular algo en la clase principal:

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

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

genera un NameError con name 'attrs' is not defined . Esto, sin embargo, parece funcionar, pero es feo:

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

¿Existe ya una solución a este error? La solución anterior no me funciona. http://stackoverflow.com/questions/21787938/inherit-and-modify-a-meta-class

No veo un algoritmo obvio para fusionar dos class Meta arbitrarios. Piense en los casos para agregar una clave a attrs , eliminar una clave de attrs , reemplazar attrs con un nuevo dictado, etc. obvio para mí cómo harías esto de una manera cuerda.

El comportamiento debería ser el mismo que si fueran subclases models.Model clases.

No estoy seguro de seguir lo que dices. Solo estoy tratando de heredar el meta de la clase principal y agregar algunas columnas. Actualicé el código en la pregunta SO anterior, que con suerte tiene un poco más de sentido.

@bradleyayers : si entiendo su solicitud correctamente, debería poder seguir esta publicación de StackOverflow para sobrescribir Meta

@pydolan Sí, consulte http://stackoverflow.com/questions/21787938/inherit-and-modify-a-meta-class para conocer otros enfoques también.

¿Fue útil esta página
0 / 5 - 0 calificaciones