代码之家  ›  专栏  ›  技术社区  ›  ravioli

python元类和继承-无法识别属性(django-tables2)

  •  0
  • ravioli  · 技术社区  · 8 年前

    我想写一个 UsersTable django-tables2 分类依据 StudentsTable 是的。此代码工作正常:

    tables.py表

    import django_tables2 as tables
    from django_tables2.utils import A # alias for accessor
    from .models.environment import Student
    
    def getEditColumn(accessor, kwargs):
        return tables.LinkColumn(
            viewname='wakemeup:edit_object',
            kwargs=kwargs,
            verbose_name='',
            text='Editar',
            accessor=accessor
        )
    
    class UsersTable(tables.Table):
    
        # Define constructor    
        def __init__(self, *args, **kwargs):
            # Call base table class constructor
            super(UsersTable, self).__init__(data = kwargs['data'])
    
            objectid = kwargs['objectid']
            objecttype = kwargs['objecttype']
    
            # Create base attributes
            self.objectid = objectid
            self.objecttype = objecttype
    
            self.mykwargs={
                'objecttype': objecttype,
                'objectid': A(objectid)
            }
    
            self.edit_link = getEditColumn(objectid, self.mykwargs)
    
        class Meta:
            model = Student
    
    class StudentsTable(UsersTable):
    
        # Call UsersTable constructor
        def __init__(self, *args, **kwargs):
            super(StudentsTable, self).__init__(*args, **kwargs)
            print(self.edit_link) # Verify edit_link has been generated
    
        class Meta:
            sequence = ('firstname','lastname','emailaddress','phonenumber','defaultsignaturescanfile','classid')
    

    但是,当我试图引用 edit_link 列继承自 用户稳定 ,我得到一个错误:

    修改后的studentstable

    class StudentsTable(UsersTable):
    
        # Call UsersTable constructor
        def __init__(self, *args, **kwargs):
            super(StudentsTable, self).__init__(*args, **kwargs)
            print(self.edit_link) # Verify edit_link has been generated
    
        class Meta:
            exclude = ('studentuserid','reputationvalue','schoolid')
            sequence = ('firstname','lastname','emailaddress','phonenumber','defaultsignaturescanfile','classid','edit_link')
    

    错误

    Exception Type: KeyError
    Exception Value: 'edit_link'
    

    好像是 Meta 类信息在继承之前被读取 编辑链接 生成列。这个 print(edit_link) 行返回所需的对象,因此该字段可用。

    我尝试了各种各样的 上课,但运气不好。

    编辑

    这是线索:

    Environment:
    
    
    Request Method: GET
    Request URL: http://127.0.0.1:8000/wakemeup/admin/student
    
    Django Version: 2.0.1
    Python Version: 3.6.4
    Installed Applications:
    ['django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'users.apps.UsersConfig',
     'wakemeup.apps.WakemeupConfig',
     'crispy_forms',
     'django_tables2']
    Installed Middleware:
    ('whitenoise.middleware.WhiteNoiseMiddleware',
     'django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware')
    
    
    Template error:
    In template C:\Program Files (x86)\Python36-32\lib\site-packages\django_tables2\templates\django_tables2\bootstrap.html, error at line 11
       edit_link
       1 : {% load django_tables2 %}
       2 : {% load i18n %}
       3 : {% block table-wrapper %}
       4 : <div class="table-container">
       5 :     {% block table %}
       6 :         <table {% if table.attrs %} {{ table.attrs.as_html }}{% else %}class="table"{% endif %}>
       7 :             {% block table.thead %}
       8 :             {% if table.show_header %}
       9 :                 <thead>
       10 :                 <tr>
       11 :                  {% for column in table.columns %} 
       12 :                     {% if column.orderable %}
       13 :                         <th {{ column.attrs.th.as_html }}><a href="{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}">{{ column.header }}</a></th>
       14 :                     {% else %}
       15 :                         <th {{ column.attrs.th.as_html }}>{{ column.header }}</th>
       16 :                     {% endif %}
       17 :                 {% endfor %}
       18 :                 </tr>
       19 :                 </thead>
       20 :             {% endif %}
       21 :             {% endblock table.thead %}
    
    
    Traceback:
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\handlers\exception.py" in inner
      35.             response = get_response(request)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
      128.                 response = self.process_exception_by_middleware(e, request)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
      126.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)
    
    File "c:\Users\ravioli\eclipse-workspace\dcp\wakemeup\views.py" in admin_list
      100.     return render(request, 'wakemeup/admin/index.html', {'objects' : objectSet, 'objecttype': objecttype})
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\shortcuts.py" in render
      36.     content = loader.render_to_string(template_name, context, request, using=using)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\loader.py" in render_to_string
      62.     return template.render(context, request)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\backends\django.py" in render
      61.             return self.template.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      175.                     return self._render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in _render
      167.         return self.nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\loader_tags.py" in render
      155.             return compiled_parent._render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in _render
      167.         return self.nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\loader_tags.py" in render
      67.                 result = block.nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\loader_tags.py" in render
      67.                 result = block.nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django_tables2\templatetags\django_tables2.py" in render
      169.             return template.render(context={'table': table}, request=request)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\backends\django.py" in render
      61.             return self.template.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      175.                     return self._render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in _render
      167.         return self.nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\loader_tags.py" in render
      155.             return compiled_parent._render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in _render
      167.         return self.nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\loader_tags.py" in render
      67.                 result = block.nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\loader_tags.py" in render
      67.                 result = block.nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      993.             output = self.filter_expression.resolve(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in resolve
      676.                 obj = self.var.resolve(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in resolve
      802.             value = self._resolve_lookup(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in _resolve_lookup
      864.                             current = current()
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\loader_tags.py" in super
      81.             return mark_safe(self.render(self.context))
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\loader_tags.py" in render
      67.                 result = block.nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\loader_tags.py" in render
      67.                 result = block.nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\defaulttags.py" in render
      314.                 return nodelist.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render
      943.                 bit = node.render_annotated(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
      910.             return self.render(context)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\template\defaulttags.py" in render
      168.             len_values = len(values)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django_tables2\columns\base.py" in __len__
      686.         return len(self.visible())
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django_tables2\columns\base.py" in visible
      643.         return list(self.itervisible())
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django_tables2\columns\base.py" in <genexpr>
      640.         return (x for x in self.iterall() if x.visible)
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django_tables2\columns\base.py" in <genexpr>
      597.         return (column for name, column in self.iteritems())
    
    File "C:\Program Files (x86)\Python36-32\lib\site-packages\django_tables2\columns\base.py" in iteritems
      614.                 yield (name, self.columns[name])
    
    Exception Type: KeyError at /wakemeup/admin/student
    Exception Value: 'edit_link'
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Matthew Story    8 年前

    我相信你的代码有两个问题。首先 Meta 属性类打开 StudentsTable 需要继承 UserTable.Meta 属性,否则它将没有 model 定义:

    class StudentsTable(UsersTable):
    
        # Call UsersTable constructor
        def __init__(self, *args, **kwargs):
            super(StudentsTable, self).__init__(*args, **kwargs)
            print(self.edit_link) # Verify edit_link has been generated
    
        class Meta(UsersTable.Meta):
            sequence = ('firstname','lastname','emailaddress','phonenumber','defaultsignaturescanfile','classid')
    

    其次是 django-tables2 这么说 sequence 枚举列。列是 fields underlying model or column attributes of the table class 以下内容:

    class StudentsTable(UsersTable):
        edit_link = tables.LinkColumn(viewname='wakemeup:edit_object', text='Editar')
    

    而不是定义 editLink 关于 __init__ 方法。

    要从模型和表实例加载链接的关键字参数,需要传递 accessor 实例到 Column 而不是字面上的夸格值。文件 LinkColumn 表明应该这样做 like this 以下内容:

    from django_tables2.utils import A 
    
    class StudentsTable(UsersTable):
        edit_link = tables.LinkColumn(viewname='wakemeup:edit_object', text='Editar', kwargs={"name": A("name"))
    

    这意味着您需要显式地而不是动态地定义所需的kwarg,这对您来说应该不是问题,因为这些是url参数,在某个地方被定义为契约。

    推荐文章