【问题标题】:django-table2: Table subclassing and Meta inner class attributesdjango-tables2:表子类化和元内部类属性
【发布时间】:2013-07-31 14:40:15
【问题描述】:

我正在尝试创建一个通用表视图,它采用模型和列名称元组,并显示模型的给定列。我的问题在于内部 Meta 类。

假设这两个模型:

# models.py

from django.db import models


class Model_a(models.Model):
    column_a_1 = models.Field() 
    column_a_2 = models.Field()
    column_a_3 = models.Field()
    column_a_4 = models.Field()
    column_a_5 = models.Field()


class Model_b(models.Model):
    column_b_1 = models.Field() 
    column_b_2 = models.Field()
    column_b_3 = models.Field()
    column_b_4 = models.Field()
    column_b_5 = models.Field()

目标是有一个单一的视图来生成正确的表,其中一些列按给定的顺序排列。所以,我有一个这样的 urls.py:

# urls.py

from django.conf.urls import patterns, url
import myapp.views as myviews
import myapp.models as mymodels


urlpatterns = patterns( '',
                       url( r'^table_a/$',
                            myviews.show_table,
                            { 'model': mymodels.Model_a,
                              'columns': ("column_a_1", "column_a_2", "column_a_3") } ),
                       url( r'^table_b/$',
                            myviews.show_table,
                            { 'model': mymodels.Model_b,
                              'columns': ("column_b_5", "column_b_2") } ) )

还有一个像这样的简单views.py:

# views.py

from django.shortcuts import render
from django_tables2 import RequestConfig
import myapp.tables as mytables


def show_table(request, model, columns):
    entries = model.objects.all()
    table = mytables.ModelTable(entries, model, columns)
    RequestConfig(request).configure(table)
    return render(request, 'table_view.html', {'dynamic-table': table})

关键在 Table 子类化中,在 tables.py 中:

# tables.py

from django_tables2 import import Table


class ModelTable(Table):

    class Meta:
        pass

    def __init__(self, data, model, columns, order_by=None, orderable=None, empty_text=None,
                 exclude=None, attrs=None, sequence=None, prefix=None,
                 order_by_field=None, page_field=None, per_page_field=None,
                 template=None, sortable=None, default=None):
        self.Meta.model = model
        self.Meta.fields = columns
        self.Meta.sequence = columns
        super(ModelTable, self).__init__(data, order_by, orderable, empty_text,
                 exclude, attrs, sequence, prefix,
                 order_by_field, page_field, per_page_field,
                 template, sortable, default)

显然,我不明白如何从 Table 子类初始化程序中设置 Table.Meta 的属性。 有趣的是,当我在模板中使用 {% render_table dynamic-table %} 时,我得到了一个空表(所以不可见),但是一个工作良好的分页器。

我的错误在哪里?

【问题讨论】:

    标签: python django inheritance python-2.7 django-tables2


    【解决方案1】:

    解决了。问题在于 Meta 类:它在 ModelTable 初始化程序之前“存在”,因此在所述初始化程序中设置 Meta 属性是没有意义的。

    启示来自this QA

    我必须定义一个新的方法来动态定义专门的类;这是我的新 tables.py :

    # tables.py
    
    from django_tables2 import import Table
    
    
    class ModelTable(Table):
        class Meta:
            pass
    
    
    def table_maker(model, columns):
        meta_class = type('Meta', (ModelTable.Meta,), {'model':model, 'fields':columns})
        table_class = type(model._meta.object_name + 'Table', (ModelTable,), {'Meta':meta_class})
        return table_class
    

    因此 views.py 也发生了一些变化:

    # views.py
    
    from django.shortcuts import render
    from django_tables2 import RequestConfig
    import myapp.tables as mytables
    
    
    def show_table(request, model, columns):
        entries = model.objects.all()
        table = mytables.table_maker(model, columns)(entries)
        RequestConfig(request).configure(table)
        return render(request, 'table_view.html', {'dynamic-table': table})
    

    现在它可以正常工作了!

    【讨论】:

      【解决方案2】:

      提交的答案有问题。

      代码实际上是行不通的,因为 table_maker 函数需要是这样的:

      def table_maker(model, columns):
          meta_class = type('Meta', (), {'model':model, 'fields':columns})
          table_class = type(model._meta.object_name + 'Table', (ModelTable,), {'Meta':meta_class})
          return table_class
      

      看,区别在于元类不应该接受任何对象。 删除对象,它可以工作:)

      这是一个参考:

      等价于:

      class X(object):
         a = 1
      

      应该是这个,(使用type类制造商):

      X = type('X', (object,), dict(a=1))
      

      我们有 Meta 而不是 object: 然后我们需要把()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-13
        • 1970-01-01
        • 2015-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多